perm filename SAIL.DCS[S,DOC]1 blob sn#011063 filedate 1972-06-11 generic text, type T, neo UTF8
00100	SAILON NO. 57.2					SAIL   1
00200	
00300	                          TABLE OF CONTENTS
00400	                                    
00500	                                    
00600	                                    
00700	                                    
00800	CONTENT                                                    PARAGRAPH
00900	   
01000	   
01100	   
01200	SECTION 1--INTRODUCTION
01300	   
01400	SECTION 2--PROGRAMS, BLOCKS, STATEMENTS
01500	   SYNTAX                                                  2- 1
01600	   EXAMPLES                                                2- 2
01700	   SEMANTICS                                               2- 3
01800	      Declarations                                         2- 3
01900	      Statements                                           2- 6
02000	      Block Names                                          2- 9
02100	      Entry Specifications                                 2-11
02200	   
02300	SECTION 3--DECLARATIONS
02400	   SYNTAX                                                  3- 1
02500	   RESTRICTIONS                                            3- 2
02600	   EXAMPLES                                                3- 6
02700	   SEMANTICS                                               3- 8
02800	      Scope of declarations                                3- 8
02900	      Type Declarations                                    3-11
03000	       Numeric Declarations                                3-13
03100	       String Declarations                                 3-15
03200	       Item Declarations                                   3-18
03300	        Items                                              3-19
03400	        Item Genesis                                       3-20
03500	        Datums                                             3-21
03600	       Itemvar Declarations                                3-22
03700	       Set Declarations                                    3-24
03800	      Array Declarations                                   3-25
03900	      Preload Specifications                               3-33
04000	      Procedure Declarations                               3-38
04100	       Formal Parameters                                   3-39
04200	       Forward Procedure Declarations                      3-42
04300	       Recursive Procedures                                3-44
04400	       External Procedures                                 3-47
04500	       Parametric Procedures                               3-51
04600	       Defaults in Procedure Declarations                  3-53
04700	       Restrictions on Procedure Declarations              3-54
04800	      Synonyms                                             3-55
04900	      Define Specification                                 3-56
05000	      Requirements                                         3-57
05100	   
     

00100	SAILON NO. 57.2					SAIL   2
00200	
00300	SECTION 4--ASSIGNMENT STATEMENTS
00400	   SYNTAX                                                  4- 1
00500	   RESTRICTION                                             4- 2
00600	   SEMANTICS                                               4- 3
00700	      Datum Assignments                                    4- 7
00800	      Swap Assignment                                      4- 8
00900	      Byte statements                                      4-10
01000	   
01100	SECTION 5--EXECUTION CONTROL STATEMENTS
01200	   SYNTAX                                                  5- 1
01300	   SEMANTICS                                               5- 2
01400	      Conditional Statements                               5- 2
01500	       If Statement                                        5- 4
01600	       If ... Else Statement                               5- 5
01700	       Ambiguity in Conditional Statements                 5- 6
01800	      Go To Statements                                     5- 8
01900	      For Statements                                       5-11
02000	      While Statement                                      5-16
02100	      Do Statement                                         5-17
02200	      Case Statements                                      5-18
02300	      Return Statement                                     5-20
02400	      Done Statement                                       5-24
02500	      Next Statement                                       5-26
02600	      Continue Statement                                   5-30
02700	   
02800	SECTION 6--PROCEDURE STATEMENTS
02900	   SYNTAX                                                  6- 1
03000	   SEMANTICS                                               6- 2
03100	      Actual Parameters                                    6- 4
03200	      Call by Value                                        6- 5
03300	      Call by Reference                                    6- 6
03400	      Procedures as Actual Parameters                      6-10
03500	      Fortran Procedures                                   6-12
03600	      Implementation Details                               6-15
03700	      Examples:                                            6-16
03800	   
03900	SECTION 7--LEAP STATEMENTS
04000	   SYNTAX                                                  7- 1
04100	   SEMANTICS                                               7- 2
04200	      LEAP Introduction                                    7- 2
04300	      General Restrictions                                 7- 7
04400	      Construction - Retrieval Distinction                 7- 8
04500	      PUT and REMOVE                                       7- 9
04600	      DELETE                                               7-10
04700	      MAKE                                                 7-11
04800	      ERASE                                                7-13
04900	      FOREACH Statement                                    7-15
05000	       Restrictions and Caveats                            7-22
05100	   
     

00100	SAILON NO. 57.2					SAIL   3
00200	
00300	SECTION 8--ASSEMBLY LANGUAGE STATEMENTS
00400	   SYNTAX                                                  8- 1
00500	   SEMANTICS                                               8- 2
00600	      Declarations in Code Blocks                          8- 3
00700	      Meaning of Instruction Operands                      8- 4
00800	      Distinctions Between START_CODE and QUICK_CODE       8- 7
00900	      Warning Concerning Default Radix                     8- 8
01000	   
01100	SECTION 9--ALGEBRAIC EXPRESSIONS
01200	   SYNTAX                                                  9- 1
01300	   SEMANTICS                                               9- 2
01400	      Conditional Expressions                              9- 2
01500	      Example                                              9- 3
01600	      Assignment Expressions                               9- 4
01700	      Example                                              9- 5
01800	      Case Expressions                                     9- 6
01900	      Example                                              9- 8
02000	      Simple Expressions                                   9- 9
02100	       The Boolean Expression Anomaly                      9-10
02200	       Precedence of Algebraic Operators                   9-13
02300	       Expression Evaluation Rules                         9-14
02400	       Algebraic Expressions                               9-15
02500	       Disjunctive Expressions                             9-18
02600	       Relational Expressions                              9-19
02700	       Arithmetic Type Conversions                         9-21
02800	       String-Arithmetic Conversions                       9-27
02900	       Bounded Expressions                                 9-29
03000	       Adding Expressions                                  9-30
03100	       Terms                                               9-33
03200	       Concatenation Operator                              9-38
03300	       Factors                                             9-39
03400	       Primaries                                           9-40
03500	        Variables and Constants                            9-41
03600	        Substrings                                         9-42
03700	      Special Length Operator (∞)                          9-45
03800	        Function Designators                               9-47
03900	        Length                                             9-50
04000	        Lop                                                9-51
04100	        Cvn                                                9-52
04200	        Lnot                                               9-53
04300	        Abs                                                9-54
04400	        Unary Minus                                        9-55
04500	        Boolean Primaries                                  9-56
04600	   ISTRIPLE                                                9-57
04700	   LDB and ILDB                                            9-58
04800	   
04900	SECTION 10--SET AND ASSOCIATIVE EXPRESSIONS
05000	   SYNTAX                                                  10- 1
05100	   SEMANTICS                                               10- 2
     

00100	SAILON NO. 57.2					SAIL   4
00200	
00300	      Set Expressions                                      10- 2
00400	      Set Primaries                                        10- 3
00500	      Item Constructs                                      10- 4
00600	      Item Selectors                                       10- 5
00700	      NEW Items                                            10- 6
00800	   NEW_ITEM Declaration                                    10- 6
00900	      ANY Construct                                        10- 7
01000	      CVI                                                  10- 8
01100	      LEAP Booleans                                        10- 9
01200	   
01300	SECTION 11--BASIC CONSTRUCTS
01400	   SYNTAX                                                  11- 1
01500	   SEMANTICS                                               11- 2
01600	      Variables                                            11- 2
01700	      Datums                                               11- 6
01800	      Identifiers                                          11- 7
01900	      Sail Reserved Words                                  11-10
02000	      Sail Predeclared Identifiers                         11-12
02100	      Arithmetic Constants                                 11-15
02200	      String Constants                                     11-19
02300	      Examples                                             11-22
02400	      Comments                                             11-24
02500	   
02600	SECTION 12--EXECUTION TIME ROUTINES
02700	   GENERAL                                                 12- 1
02800	      Scope                                                12- 1
02900	      Notational Conventions                               12- 3
03000	      Example                                              12- 5
03100	   I/O ROUTINES                                            12- 6
03200	      Open                                                 12- 6
03300	      Close, Closin, Closo                                 12-10
03400	      Getchan                                              12-12
03500	      Release                                              12-14
03600	      Lookup, Enter                                        12-17
03700	      Rename                                               12-21
03800	      Breakset                                             12-22
03900	      Setbreak                                             12-35
04000	      Stdbrk                                               12-37
04100	      Input                                                12-40
04200	      Scan                                                 12-43
04300	      Out                                                  12-45
04400	      Linout                                               12-46
04500	      Wordin                                               12-48
04600	      Arryin                                               12-50
04700	      Wordout                                              12-53
04800	      Arryout                                              12-55
04900	      Mtape                                                12-57
05000	      Useti, Useto                                         12-59
05100	      Realin, Intin                                        12-61
     

00100	SAILON NO. 57.2					SAIL   5
00200	
00300	      Realscan, Intscan                                    12-66
00400	      Teletype I/O Functions                               12-68
00500	      Pseudo-teletype functions (Stanford only)            12-70
00600	   STRING MANIPULATION ROUTINES                            12-72
00700	      Equ                                                  12-73
00800	   TYPE CONVERSION ROUTINES                                12-75
00900	      Setformat                                            12-75
01000	      Getformat                                            12-78
01100	      Cvs                                                  12-80
01200	      Cvos                                                 12-82
01300	      Cvis                                                 12-84
01400	      Cvsi                                                 12-86
01500	      New_Pname                                            12-88
01600	      Del_Pname                                            12-90
01700	      Cve, Cvf, Cvg                                        12-92
01800	      Cvstr                                                12-97
01900	      Cvxstr                                               12-99
02000	      Cvd                                                  12-101
02100	      Cvo                                                  12-103
02200	      Cvasc                                                12-105
02300	      Cvsix                                                12-107
02400	      Cvfil                                                12-109
02500	      Arrinfo                                              12-110
02600	      Arrblt                                               12-112
02700	      Arrtran                                              12-114
02800	   LIBERATION-FROM-SAIL ROUTINES                           12-116
02900	      Code                                                 12-116
03000	      Call                                                 12-118
03100	      Usercon                                              12-120
03200	      Usererr                                              12-124
03300	      Point                                                12-126
03400	   
03500	SECTION 13--USE OF DEFINE
03600	      Defining Macros                                      13- 1
03700	      String Constants in Macro Bodies                     13- 4
03800	      Using Macros                                         13- 5
03900	      Macro Parameters                                     13- 6
04000	       Example                                             13- 8
04100	      Actual Parameter Expansion                           13- 9
04200	       Examples                                            13-11
04300	   
04400	SECTION 14--COMPILER OPERATION
04500	   COMMAND FORMAT                                          14- 1
04600	      Semantics                                            14- 2
04700	       Rpg Mode                                            14-12
04800	       Switches                                            14-13
04900	      Debugging modes                                      14-14
05000	   ERROR MESSAGES                                          14-19
05100	   STORAGE ALLOCATION                                      14-22
     

00100	SAILON NO. 57.2					SAIL   6
00200	
00300	   
00400	SECTION 15--PROGRAM OPERATION
00500	   LOADING AND STARTING SAIL PROGRAMS                      15- 1
00600	      Loading                                              15- 1
00700	      Starting the Program -- Normal Operation             15- 2
00800	      Starting the Program in "RPG" Mode                   15- 3
00900	      Starting the Program with Allocation Modifications   15- 4
01000	   ERROR MESSAGES                                          15- 5
01100	   DEBUGGING                                               15- 9
01200	      Symbols                                              15-10
01300	      Blocks                                               15-13
01400	      Sail-Generated Symbols                               15-14
01500	      Warnings                                             15-15
01600	       Long Names                                          15-16
01700	   
01800	SECTION 16--PROGRAM STRUCTURE
01900	   THE SAIL CORE IMAGE (REQUIRED)                          16- 1
02000	      Main Program                                         16- 2
02100	      Storage Allocation, Basic Utilities                  16- 4
02200	      Other Execution-Time Routines                        16- 6
02300	   OPTIONAL ADDITIONS                                      16- 7
02400	      Separately Compiled Procedures                       16- 7
02500	      Fortran Procedures                                   16-11
02600	      Assembly Language Procedures                         16-12
02700	      Others                                               16-13
02800	   
02900	SECTION 17--IMPLEMENTATION INFORMATION
03000	   STORAGE LAYOUT                                          17- 1
03100	      User Table                                           17- 1
03200	      Storage Allocation Routines                          17- 5
03300	       Corget                                              17- 6
03400	       Correl                                              17-10
03500	       Corinc                                              17-11
03600	       Caninc                                              17-12
03700	       Corbig                                              17-13
03800	   STRINGS                                                 17-15
03900	      String Descriptors                                   17-15
04000	      String Operations                                    17-20
04100	       Cat                                                 17-21
04200	       Substr                                              17-22
04300	       String to Integer                                   17-26
04400	       Putch                                               17-27
04500	       Lop Details                                         17-28
04600	      String Space                                         17-29
04700	      Parameters Used by String Operations                 17-31
04800	      String Garbage Collection                            17-32
04900	      String-Oriented Machine Language Routines            17-33
05000	   ARRAY IMPLEMENTATION                                    17-35
05100	      Form                                                 17-35
     

00100	SAILON NO. 57.2					SAIL   7
00200	
00300	      Explanation                                          17-36
00400	      Array Allocation                                     17-37
00500	       Dynamic Arrays                                      17-37
00600	       Built-In Arrays                                     17-40
00700	      Array Access Code                                    17-44
00800	   PROCEDURE IMPLEMENTATION                                17-48
00900	      Procedure Body                                       17-49
01000	       Discussion                                          17-50
01100	      Procedure Calling Sequences                          17-51
01200	       Discussion                                          17-52
01300	   
01400	SECTION 18--APPENDIX -- USEFUL SUMMARIES
01500	   ARITHMETIC TYPE-CONVERSION TABLE                        18- 1
01600	   SAIL RESERVED WORDS                                     18- 2
01700	   SAIL PRE-DECLARED IDENTIFIERS                            18- 3
01800	   CHARACTER-IDENTIFIER EQUIVALENCES                       18- 4
01900	   PARAMETERS TO THE OPEN FUNCTION                         18- 5
02000	   BREAKSET MODES                                          18- 6
02100	   MTAPE COMMANDS                                          18- 7
02200	   COMMAND SWITCHES                                        18- 8
02300	   DEBUGGING MODES                                         18- 9
02400	   VALID RESPONSES TO ERROR MESSAGES                       18-10
02500	   NON-FATAL ERROR, EXCEPTIONAL CONDITION RETURN CODES     18-11
02600	   
02700	SECTION 19--BIBLIOGRAPHY
02800	   
     

00100	SAILON NO. 57.2					SAIL   1-1
00200	
00300	                              SECTION 1
00400	                                    
00500	                             INTRODUCTION
00600	                                    
00700	   
00800	   
00900	1-1.    SAIL is  a  high-level  programming  system  for  the  PDP-10
01000	computer.  It includes an extended ALGOL compiler and a companion set
01100	of execution-time routines.  A  non-standard  ALGOL  60  compiler  is
01200	extended  to  provide  facilities  for describing manipulations of an
01300	associative data  structure.   This  structure  contains  information
01400	about  ITEMS,  stored  as unordered collections of items (sets) or as
01500	ordered triples of items (associations).  The algebraic  capabilities
01600	of  the  language are linked to the associative capabilities by means
01700	of the DATUM operator, which can associate with any ITEM an algebraic
01800	datum.
01900	   
02000	   
02100	1-2.    Several  forerunners (namely the GOGOL compilers developed at
02200	the Stanford Artificial Intelligence Project) have contributed to the
02300	general  appearance  of  the  non-associative  portions  of  the SAIL
02400	language.  The associative data  structure  is  a  slightly  reworked
02500	version  of  the LEAP language, which was designed by J.  Feldman and
02600	P.  Rovner, and  implemented  on  Lincoln  Laboratory's  TX-2.   This
02700	language  is  described  in  some  detail  in an article entitled "An
02800	Algol-Based Associative Language" in the August, 1969  issue  of  the
02900	ACM Communications [Feldman&Rovner].  The implementation was modified
03000	to tolerate the non-paging environment of the PDP-10.
03100	   
03200	   
03300	1-3.    SAIL in a sense has something for everyone.   For  those  who
03400	think in ALGOL, SAIL has ALGOL.  For those who want the most from the
03500	PDP-10 and the time-sharing system, SAIL allows flexible  linking  to
03600	hand-coded  machine  language  programs.   For those who have complex
03700	input/output requirements, the language provides complete  access  to
03800	the  I/O  facilities  of  the PDP-10 system.  For those who aspire to
03900	speed, SAIL generates fairly good code.  The user should, however, be
04000	warned  that  SAIL  falls  several man-decades short of the extensive
04100	testing and optimization efforts contained in the histories  of  most
04200	commercial compilers.
04300	   
04400	   
04500	   
04600	                                             D.  Swinehart
04700	                                             R.  Sproull
04800	                                             November, 1969
04900	                                             Revised January, 1971
05000	                                                
05100	   
     

00100	SAILON NO. 57.2					SAIL   2-1
00200	
00300	                              SECTION 2
00400	                                    
00500	                     PROGRAMS, BLOCKS, STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	2-1.    
01300	   
01400	
01500	<program>                ::= <block>
01600	                         ::= <entry_specification> <block> 
01700	
01800	<block>                  ::= <block_head> ; <compound_tail> 
01900	
02000	<block_head>             ::= BEGIN <declaration>
02100	                         ::= BEGIN <block_name> <declaration>
02200	                         ::= <block_head> ; <declaration> 
02300	
02400	<compound_tail>          ::= <statement> END
02500	                         ::= <statement> END <block_name>
02600	                         ::= <statement> ; <compound_tail> 
02700	   
02800	   
02900	
03000	<statement>              ::= <block>
03100	                         ::= <compound_statement>
03200	                         ::= <assignment>
03300	                         ::= <byte_statement>
03400	                         ::= <conditional_statement>
03500	                         ::= <if_statement>
03600	                         ::= <go_to_statement>
03700	                         ::= <for_statement>
03800	                         ::= <while_statement>
03900	                         ::= <do_statement>
04000	                         ::= <case_statement>
04100	                         ::= <return_statement>
04200	                         ::= <done_statement>
04300	                         ::= <next_statement>
04400	                         ::= <continue_statement>
04500	                         ::= <leap_statement>
04600	                         ::= <procedure_statement>
04700	                         ::= <code_block>
04800	                         ::= <define_specification>
04900	                         ::= <string_constant> <statement>
05000	                         ::= <label_identifier> : <statement>
05100	                         ::= <empty> 
     

00100	SAILON NO. 57.2					SAIL   2-1
00200	
00300	
00400	<compound_statement>     ::= BEGIN <compound_tail>
00500	                         ::= BEGIN <block_name> <compound_tail> 
00600	
00700	<block_name>             ::= <string_constant> 
00800	
00900	<entry_specification>    ::= ENTRY <id_list> 
01000	   
01100	   
01200	   
01300	EXAMPLES
01400	   
01500	   
01600	2-2.    
01700	Given:
01800	    S is a statement,
01900	    Sc is a Compound Statement,
02000	    D is a Declaration,
02100	    B is a Block.
02200	
02300	Then:
02400	    (Sc)    BEGIN S; S; S; ... ; S END
02500	    (Sc)    BEGIN "SORT" S; S; ... ;S END
02600	    (B)     BEGIN D; D; D; ... ; S; S; S; ... ; S END
02700	    (B)     BEGIN "ENTER NEW INFO" D;  D; ... ; S; ... ;S END
02800	
02900				are syntactically valid SAIL constructs.
03000	
03100	   
03200	   
03300	SEMANTICS
03400	   
03500	Declarations
03600	   
03700	   
03800	2-3.    SAIL   programs   are  organized  in  the  traditional  block
03900	structure of ALGOL-60.
04000	   
04100	   
04200	2-4.    Declarations serve to define the data types and dimensions of
04300	simple  and  subscripted  (array)  variables  (arithmetic  variables,
04400	strings, sets, and items).  They are also used to describe procedures
04500	(subroutines)  and  name  program  labels.  The DEFINE construct (see
04600	DECLARATIONS,  3-1,  USE  OF  DEFINE,  13-0)  may  also   appear   in
04700	declarations.
     

00100	SAILON NO. 57.2					SAIL   2-5
00200	
00300	   
00400	   
00500	2-5.    Any  identifier referred to in a program must be described in
00600	some declaration.  An identifier may only be referenced by statements
00700	within the scope (see Scope of declarations, 3-8) of its declaration.
00800	   
00900	   
01000	Statements
01100	   
01200	   
01300	2-6.    As  in  ALGOL,  the  statement  is  the  fundamental  unit of
01400	operation in the SAIL language.  Since a statement within a block  or
01500	compound  statement  may itself be a block or compound statement, the
01600	concept of statement must be understood recursively.
01700	   
01800	   
01900	2-7.    This definition of a block as a statement has  virtues  other
02000	than  its  syntactic  niceness.   In  many  ways a block behaves as a
02100	single complex statement; most importantly, no transfers (jumps)  may
02200	be  made  to  any statement within it except the first (There are now
02300	(unfortunately?)  exceptions,  see  Go  To  Statements,  5-8).   This
02400	assures  proper  allocation  and initialization of the data space for
02500	the block.
02600	   
02700	   
02800	2-8.    The  block  representing  the  program  is   known   as   the
02900	"outer block".   All  blocks internal to this one will be referred to
03000	as "inner blocks".
03100	   
03200	   
03300	Block Names
03400	   
03500	   
03600	2-9.    The block name  construct  is  used  to  describe  the  block
03700	structure  of  a  SAIL  program  to a symbolic debugging routine (see
03800	DEBUGGING, 15-9).  The name of the outer block becomes the  title  of
03900	the  binary output file (not necessarily the file name).  In addition,
04000	if a block name is used following an END, the  compiler  compares  it
04100	with  the  block  name  which  followed  the  corresponding BEGIN.  A
04200	mismatch is reported to the user as evidence  of  a  missing  (extra)
04300	BEGIN  or  END somewhere.  The block name is also used in conjunction
04400	with the DONE, NEXT, and CONTINUE  statements  (see  Done  Statement,
04500	5-24 and following).
04600	   
04700	   
04800	2-10.    The <string_constant> <statement> construct is equivalent in
04900	action to the <statement> alone; that is, the string constant  serves
05000	only as a comment.
     

00100	SAILON NO. 57.2					SAIL   2-10
00200	
00300	   
00400	   
00500	Entry Specifications
00600	   
00700	   
00800	2-11.    See Separately Compiled Procedures, 16-7.
     

00100	SAILON NO. 57.2					SAIL   3-1
00200	
00300	                              SECTION 3
00400	                                    
00500	                             DECLARATIONS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	3-1.    
01300	
01400	<id_list>                ::= <identifier>
01500	                         ::= <identifier> , <id_list> 
01600	   
01700	   
01800	
01900	<declaration>            ::= <type_declaration>
02000	                         ::= <array_declaration>
02100	                         ::= <preload_specification>
02200	                         ::= <label_declaration>
02300	                         ::= <procedure_declaration>
02400	                         ::= <define_specification>
02500	                         ::= <synonym_declaration>
02600	                         ::= <requirement> 
02700	   
02800	   
02900	
03000	<type>                   ::= <algebraic_type>
03100	                         ::= <leap_type>
03200	                         ::= <algebraic_type> <leap_type>
03300	                         ::= <algebraic_type> ARRAY <leap_type>
03400	                         ::= SET
03500	                         ::= SET <leap_type>
03600	                         ::= SET ARRAY <leap_type>
03700	                         ::= <type_qualifier> <type> 
03800	
03900	<algebraic_type>         ::= REAL
04000	                         ::= INTEGER
04100	                         ::= BOOLEAN
04200	                         ::= STRING 
04300	
04400	<leap_type>              ::= ITEM
04500	                         ::= ITEMVAR 
     

00100	SAILON NO. 57.2					SAIL   3-1
00200	
00300	
00400	<type_qualifier>         ::= EXTERNAL
00500	                         ::= INTERNAL
00600	                         ::= SAFE
00700	                         ::= FORWARD
00800	                         ::= RECURSIVE
00900	                         ::= FORTRAN
01000	                         ::= OWN
01100	                         ::= SHORT 
01200	   
01300	   
01400	
01500	<type_declaration>       ::= <type> <id_list> 
01600	   
01700	   
01800	
01900	<array_declaration>      ::= <type> ARRAY <array_list> 
02000	
02100	<array_list>             ::= <array_segment>
02200	                         ::= <array_list> , <array_segment> 
02300	
02400	<array_segment>          ::= <id_list> [ <bound_pair_list> ] 
02500	
02600	<bound_pair_list>        ::= <bound_pair>
02700	                         ::= <bound_pair_list> , <bound_pair> 
02800	
02900	<bound_pair>             ::= <lower_bound> : <upper_bound> 
03000	
03100	<lower_bound>            ::= <algebraic_expression> 
03200	
03300	<upper_bound>            ::= <algebraic_expression> 
03400	
03500	<preload_specification>  ::= PRELOAD_WITH <preload_list> 
03600	
03700	<preload_list>           ::= <preload_element>
03800	                         ::= <preload_list> , <preload_element> 
03900	
04000	<preload_element>        ::= <expression>
04100	                         ::= [expression] <expression> 
04200	   
04300	   
04400	
04500	<label_declaration>      ::= LABEL <id_list> 
04600	   
04700	   
     

00100	SAILON NO. 57.2					SAIL   3-1
00200	
00300	
00400	<procedure_declaration>  ::= PROCEDURE <identifier> <procedure_head> 
00500	                                <procedure_body>
00600	                         ::= <type> PROCEDURE <identifier> 
00700	                                <procedure_head> <procedure_body> 
00800	
00900	<procedure_head>         ::= <empty>
01000	                         ::= ( <formal_param_decl> ) 
01100	
01200	<procedure_body>         ::= <empty>
01300	                         ::= ; <statement> 
01400	
01500	<formal_param_decl>      ::= <formal_parameter_list>
01600	                         ::= <formal_parameter_list> ; 
01700	                                <formal_param_decl> 
01800	
01900	<formal_parameter_list>  ::= <formal_type> <id_list> 
02000	
02100	<formal_type>            ::= <simpler_formal_type>
02200	                         ::= REFERENCE <simpler_formal_type>
02300	                         ::= VALUE <simpler_formal_type> 
02400	
02500	<simpler_formal_type>    ::= <type>
02600	                         ::= <type> ARRAY
02700	                         ::= <type> PROCEDURE 
02800	   
02900	   
03000	
03100	<define_specification>   ::= DEFINE <definition_list> 
03200	
03300	<definition_list>        ::= <definition>
03400	                         ::= <definition> , <definition_list> 
03500	
03600	<definition>             ::= <define_identifier> = <define_body> 
03700	
03800	<define_identifier>      ::= <identifier>
03900	                         ::= <identifier> ( <id_list> ) 
04000	
04100	<define_body>            ::= <string_constant> 
04200	
04300	<synonym_declaration>    ::= LET <synonym_list> 
04400	
04500	<synonym_list>           ::= <synonym>
04600	                         ::= <synonym_list> , <synonym> 
04700	
04800	<synonym>                ::= <identifier> = <reserved_word> 
04900	
05000	<requirement>            ::= REQUIRE <require_list> 
     

00100	SAILON NO. 57.2					SAIL   3-1
00200	
00300	
00400	<require_list>           ::= <require_element>
00500	                         ::= <require_list> , <require_element> 
00600	
00700	<require_element>        ::= <arithmetic_constant> <space_spec>
00800	                         ::= <string_constant> <file_spec> 
00900	
01000	<space_spec>             ::= STRING_SPACE
01100	                         ::= SYSTEM_PDL
01200	                         ::= STRING_PDL
01300	                         ::= ARRAY_PDL
01400	                         ::= NEW_ITEMS
01500	                         ::= PNAMES 
01600	
01700	<file_spec>              ::= LOAD_MODULE
01800	                         ::= LIBRARY
01900	                         ::= SOURCE_FILE
02000	                         ::= SEGMENT_FILE
02100	                         ::= SEGMENT_NAME 
02200	   
02300	   
02400	   
02500	RESTRICTIONS
02600	   
02700	   
02800	3-2.    For  simplicity,  the  type_qualifiers are listed in only one
02900	syntactic class.  Although their uses are always  valid  when  placed
03000	according  to  the  above syntax, most of them only have meaning when
03100	applied to particular subsets of these productions:
03200	   
03300	   SAFE is only meaningful in array declarations
03400	   INTERNAL/EXTERNAL  have  no   meaning   in   formal   parameter
03500	   declarations
03600	   FORWARD,  RECURSIVE, and FORTRAN have meaning only in procedure
03700	   type specifications.
03800	   ITEM ARRAYS and PROCEDURES do not exist (use ITEMVAR).
03900	   SHORT  has  meaning  only  when  applied  to  INTEGER  or  REAL
04000	   entities.
04100	   
04200	   
04300	3-3.    For   array   declarations  in  the  outer  block  substitute
04400	<constant_expression> for <algebraic_expression> in  the  productions
04500	for <lower_bound> and <upper_bound>.
04600	   
04700	   
04800	3-4.    A  label must be declared in the innermost block in which the
04900	statement being labeled appears.
     

00100	SAILON NO. 57.2					SAIL   3-5
00200	
00300	   
00400	   
00500	3-5.    The  syntax  for  procedure  declarations  requires  semantic
00600	embellishment  (see  Procedure  Declarations,  3-38) in order to make
00700	total sense.  In particular, a procedure body may be empty only in  a
00800	restricted class of declarations.
00900	   
01000	   
01100	EXAMPLES
01200	   
01300	   
01400	3-6.    Let I,J,K,L,X,Y, and P be identifiers, S a statement:
01500	   
01600	(<type_declaration>)       INTEGER I,J,K
01700	                           EXTERNAL REAL X,Y
01800	                           ITEM I
01900	                           SET P
02000	                           ITEMVAR X
02100	                           REAL ITEM Y
02200	                           INTEGER ARRAY ITEM J[X:Y]
02300	                           INTERNAL STRING K
02400	   
02500	   
02600	(<array_declaration>)      INTEGER ARRAY X[0:10,0:10]
02700	                           REAL ARRAY Y[X:P(L)]; Comment illegal
02800	                               in outer block
02900	                           STRING ARRAY I[0:IF BIG THEN 30 ELSE 3]
03000	                           ITEMVAR ARRAY K[0:5,1:L]
03100	                           REAL ARRAY ITEMVAR ARRAY P[0:15]
03200	   
03300	   
03400	(<label_declaration>)      LABEL L,X,Y
03500	   
03600	   
03700	(<procedure declaration>)  PROCEDURE P; S
03800	                           PROCEDURE P(INTEGER I,J;
03900	                               REFERENCE REAL X; REAL Y) ; S
04000	                           INTEGER PROCEDURE P (REAL PROCEDURE L;
04100	                               STRING I,J; INTEGER ARRAY K); S
04200	                           EXTERNAL PROCEDURE P(REAL X)
04300	                           FORWARD INTEGER PROCEDURE X(INTEGER I)
04400	                           FORTRAN REAL PROCEDURE SIN
04500	   
04600	   
04700	(<define_specification>)   DEFINE CR="'15", LF="'12",
04800	                               CRLF = "(CR&LF)",
04900	                               TTY="1",
05000	                               TYPE(MSG)="OUT(TTY,MSG&CRLF)"
     

00100	SAILON NO. 57.2					SAIL   3-7
00200	
00300	   
00400	   
00500	3-7.    Note that these sample declarations are all given without the
00600	semicolons  which  would  normally separate them from the surrounding
00700	declarations and statements.  Here is a sample block to bring it  all
00800	together (again, let S be any statement, D any declaration, and other
00900	identifiers as above:
01000	   
01100	
01200	BEGIN "SAMPLE BLOCK"
01300	 INTEGER I,J,K; 
01400	 REAL X,Y;
01500	 STRING A;
01600	 INTEGER PROCEDURE P(REFERENCE REAL X; REAL Y);
01700	  BEGIN
01800	   D; D; D; ... ;S; ... ; S
01900	  END "P";
02000	
02100	 REAL ARRAY DIPHTHONGS[0:10,1:100];
02200	
02300	 S;  S;  S;  S
02400	END "SAMPLE BLOCK"
02500	
02600	   
02700	   
02800	SEMANTICS
02900	   
03000	Scope of declarations
03100	   
03200	   
03300	3-8.    Every  block  automatically  introduces  a   new   level   of
03400	nomenclature.   Any  identifier declared in a block's head is said to
03500	be LOCAL to that block.  This means that:
03600	   
03700	  a.  The entity represented by this identifier inside  the  block
03800	      has no existence outside the block.
03900	         
04000	  b.   Any  entity  represented by the same identifier outside the
04100	      block is completely inaccessible (unless it has been  passed
04200	      as a parameter) inside the block.
04300	   
04400	   
04500	3-9.    An  identifier  occurring  within  an  inner  block  and  not
04600	declared within that block will be nonlocal (global) to it; that  is,
04700	the identifier will represent the same entity inside the block and in
04800	the block or blocks within which it is nested, up  to  and  including
04900	the level in which the identifier is declared.
     

00100	SAILON NO. 57.2					SAIL   3-10
00200	
00300	   
00400	   
00500	3-10.    The  Scope  of  an  entity is the set of blocks in which the
00600	entity is represented, using the above rules, by its identifier.   An
00700	entity may not be referenced by any statement outside its scope.
00800	   
00900	   
01000	Type Declarations
01100	   
01200	   
01300	3-11.    SAIL  reserves  either  one  or  two  36-bit  words for each
01400	identifier appearing in a type declaration (exception -- no space  is
01500	reserved for items -- see Item Declarations, 3-18).  The use of these
01600	cells falls into two classes -- values and descriptors  --  depending
01700	on  the type preceding the identifier.  If an identifier represents a
01800	REAL or INTEGER (BOOLEAN) variable or an ITEMVAR, its value is stored
01900	directly  in  the  reserved  cell.   For strings (2 words, see String
02000	Declarations, 3-15) and sets (1 word,  see  Set  Declarations,  3-24)
02100	internal descriptors are placed in the reserved cells which allow the
02200	running program to access these entities.  These differences are  not
02300	reflected  in  the  SAIL syntax.  The user may treat entities of both
02400	kinds as if their values were directly  accessible  in  the  reserved
02500	locations.   For this reason we will henceforth refer synonymously to
02600	a simple identifier (one declared in  a  type  declaration)  and  the
02700	simple variable it represents, as a "variable".
02800	   
02900	   
03000	3-12.    Items  do  not  entirely  conform to the structure described
03100	above.  Please suppress any  enpuzzlement  concerning  the  roles  of
03200	items  and  itemvars  until after you have read the paragraph on Item
03300	Declarations, 3-18.
03400	   
03500	   
03600	Numeric Declarations
03700	   
03800	   
03900	3-13.    Identifiers which appear in  type  declarations  with  types
04000	REAL  or  INTEGER  can  subsequently  be  used  to  refer  to numeric
04100	variables.  An Integer variable may take  on  values  from  -2↑35  to
04200	2↑35-1  (-2↑26  to  2↑26-1  for SHORT INTEGERS).  A Real variable may
04300	take on positive and negative values from about 10↑-38 to 10↑38  with
04400	a  precision  of  27  bits  (same  range for SHORT REALs as for SHORT
04500	INTEGERs.  REAL and INTEGER variables (and constants) may be used  in
04600	the  same  arithmetic  expressions;  type conversions are carried out
04700	automatically (see Arithmetic  Type  Conversions,  9-21  below)  when
04800	necessary.
     

00100	SAILON NO. 57.2					SAIL   3-14
00200	
00300	   
00400	   
00500	3-14.    The  BOOLEAN type is currently identical to INTEGER.  As you
00600	will see, BOOLEAN and algebraic  expressions  are  really  equivalent
00700	syntactically.  The syntactic context in which they appear determines
00800	their meaning.  Algorithms for determining the Boolean and  algebraic
00900	interpretations  of  these  expressions  will  be given below.  The
01000	declarator BOOLEAN is included for program clarity.
01100	   
01200	   
01300	String Declarations
01400	   
01500	   
01600	3-15.    A variable defined in a String  declaration  is  a  two-word
01700	descriptor  containing  the information necessary to represent a SAIL
01800	character string.
01900	   
02000	   
02100	3-16.    A  String  may  be  thought   of   as   a   variable-length,
02200	one-dimensional  array  of  7-bit  ASCII  characters.  Its descriptor
02300	contains a character count and a byte pointer to the first  character
02400	(see STRINGS, 17-15).  Strings originate as constants at compile time
02500	(String Constants, 11-19), as the result of a String INPUT  operation
02600	from  some  device  (see  Input, 12-40), or from the concatenation or
02700	decomposition  of  already  existing   strings   (see   Concatenation
02800	Operator, 9-38 and Substrings, 9-42).
02900	   
03000	   
03100	3-17.    When  strings appear in arithmetic operations or vice-versa,
03200	a somewhat arbitrary conversion is performed  to  obtain  the  proper
03300	type   (by   arbitrary  we  do  not  mean  to  imply  random  --  see
03400	String-Arithmetic Conversions, 9-27).  For this reason arithmetic and
03500	String  variables  are referred to as "algebraic variables" and their
03600	corresponding  expressions  are   called   "algebraic   expressions".
03700	(Suggestions  for  a  better term will be given a high priority).  No
03800	other direct,  or  "forced",  conversions  (except  for  Integer/Real
03900	conversions) are present in the language.
     

00100	SAILON NO. 57.2					SAIL   3-18
00200	
00300	   
00400	   
00500	Item Declarations
00600	   
00700	Prerequisite
00800	   
00900	   
01000	3-18.    Please  make  no  attempt to understand the sections of this
01100	manual describing the associative capabilities of the  SAIL  language
01200	until  you  have  read  the  article  describing  its basic flavor in
01300	[Feldman&Rovner].  If you do not have access to a copy of  the  CACM,
01400	reprints   are   available  from  the  authors.   The  structure  and
01500	operations of the associative portions of LEAP and SAIL are so nearly
01600	identical  that  it  seemed  foolish  to repeat them completely here.
01700	However, a full description of the syntax and a brief  discussion  of
01800	each construct is given here.
01900	   
02000	   
02100	Items
02200	   
02300	   
02400	3-19.    The  "Associative  memory" of the SAIL system is constructed
02500	from a universe of items and a universe of associations  among  these
02600	items.   An Item is an entity which is represented inside the machine
02700	by its internal name and is otherwise uninterpreted.   Items  may  be
02800	combined  to  form  "associations"  which express facts (see Triples,
02900	7-6).   They  may  also  be  collected  into  unordered   sets   (Set
03000	Declarations, 3-24).
03100	   
03200	   
03300	Item Genesis
03400	   
03500	   
03600	3-20.    The   universe  of  items  is  divided  into  three  classes
03700	differing in the way an Item enters it:
03800	
03900	  1)   A  declared  Item  results  from  each  declaration  of  an
04000	      identifier  to  be  of  type ITEM.  The declaration causes a
04100	      single internal name to be created for the  item.   Declared
04200	      items  do  not  obey the usual rules in recursive functions.
04300	      In particular, items behave as if they were declared in  the
04400	      outer  block.   Although  they  may referred to by name only
04500	      within  the  scope  of  their  declarations  (see  Scope  of
04600	      declarations,  3-8),  they  may be accessed from outside the
04700	      scope if they have been included in (and not  removed  from)
04800	      any  associations or sets, or assigned to itemvars which are
04900	      still accessible.  They are not deleted at  block-exit.   It
05000	      might   be  helpful  to  think  of  declared  items  as  the
05100	      associative analogue of algebraic constants.
     

00100	SAILON NO. 57.2					SAIL   3-20
00200	
00300	
00400	  2)   A  created  Item  results  from  the  execution  of  a  NEW
00500	      expression  (see  NEW Items, 10-6).  Any created Item may be
00600	      deleted from the  universe  of  items  (see  DELETE,  7-10).
00700	      Again,  usual  block  structure  rules  do  not apply to any
00800	      items.
00900	
01000	  3)   An  association  Item  results  from  the  execution  of  a
01100	      bracketed  construction triple (see Construction - Retrieval
01200	      Distinction, 7-8).  These may also be explicitly, but  never
01300	      automatically, deleted.
01400	   
01500	   
01600	Datums
01700	   
01800	   
01900	3-21.    An  Item  of  type  1)  or  2)  may have an associated value
02000	(Datum) of algebraic or SET type which can be used  or  altered  like
02100	any  other  variable.   This  Datum  may  represent a simple or array
02200	variable of any type except ITEM or ITEMVAR.  Datums may be  referred
02300	to by use of the DATUM operator (see Datums, 11-6, Datum Assignments,
02400	4-7).
02500	   
02600	   
02700	Itemvar Declarations
02800	   
02900	   
03000	3-22.    An Itemvar is a variable whose value is an  Item  (it  is  a
03100	reference  to  an Item).  Just as the statements "X←3; A←X" and "A←3"
03200	are equivalent with respect to A, the  statements  "X←EDGE; A←X"  and
03300	"A←EDGE"  are  equivalent with respect to A, if X and A are itemvars,
03400	EDGE an item.  The use of an Itemvar is equivalent to the use of  the
03500	Item  to  which  it  refers.   The  difference is, of course that the
03600	Itemvars may represent different Items at different times.
03700	   
03800	   
03900	3-23.    Just as algebraic variables may be bound as  loop  variables
04000	in  FOR statements, Itemvars observe a special binding in the FOREACH
04100	statement.  This very important construct  is  described  in  FOREACH
04200	Statement, 7-15 below.
     

00100	SAILON NO. 57.2					SAIL   3-24
00200	
00300	   
00400	   
00500	Set Declarations
00600	   
00700	   
00800	3-24.    Because  the  answers  to  many  associative  questions  are
00900	many-valued (all the sons of Harry, for example), sets of  Items  are
01000	provided.   A SAIL Set is an unordered collection of Items containing
01100	at most one occurrence of any  single  Item.   The  more  common  Set
01200	operations are available for convenient manipulation of Sets.
01300	   
01400	   
01500	Array Declarations
01600	   
01700	   
01800	3-25.    In  general,  any  data type which is applicable to a simple
01900	variable may be applied in  an  Array  declaration  to  an  array  of
02000	variables.   Note,  however,  the restriction (see RESTRICTIONS, 3-2)
02100	prohibiting  ITEM  ARRAY  X  as  a  legal  declaration   (Items   are
02200	"constants"),  although  ITEMVAR  Arrays  are  allowed.   The  entity
02300	represented by  the  name  of  an  Array,  qualified  with  subscript
02400	expressions  to locate a particular element (e.g.  A[I,J]) behaves in
02500	every way like a simple variable.  Therefore, in the future we  shall
02600	refer  to  both  simple  variables  and  single  elements  of  Arrays
02700	(subscripted  variables)  as  "variables".   The  formal  syntax  for
02800	<variable> can be found in Variables, 11-2.
02900	   
03000	   
03100	3-26.    Each  subscript  for  an Array which is not qualified by the
03200	SAFE attribute will be checked to ensure that  it  falls  within  the
03300	lower  and  upper  bounds  given  for the dimension it specifies.  An
03400	overflow triggers an  error  message  and  job  abortion.   The  SAFE
03500	declaration inhibits this checking, resulting in faster, smaller, and
03600	bolder code.
03700	   
03800	   
03900	3-27.    Arrays are stored by rows.  That is, if A[I,J] is stored  in
04000	location 10000, then A[I,J+1] is stored in location 10001.
04100	   
04200	   
04300	3-28.    There is no limit to the number of dimensions allowed for an
04400	Array.  However, the efficiency of Array references tends to decrease
04500	for  large  dimensions.   Avoid  large  dimensionality  if  it is not
04600	necessary.
     

00100	SAILON NO. 57.2					SAIL   3-29
00200	
00300	   
00400	   
00500	3-29.    The Item instances stored  in  an  Itemvar  Array  may  have
00600	datums which are themselves algebraic or Set Arrays.  This provides a
00700	good deal of power,  since  an  Array  of  algebraic  values  can  be
00800	dynamically associated with any Item.
00900	   
01000	   
01100	3-30.    OWN  Arrays  are  available  in part.  They must be declared
01200	with constant bounds, since fixed  storage  is  allocated  for  these
01300	Arrays.   They  are  initialized to zero when the block in which they
01400	are declared is entered (except  in  preloaded  Arrays,  see  Preload
01500	Specifications,  3-33).   A  certain  degree  of  extra efficiency is
01600	possible in accessing  these  Arrays,  since  they  may  be  assigned
01700	absolute  core  locations  by  the  compiler, eliminating some of the
01800	address arithmetic.  Constant bounds always add a little  efficiency,
01900	even in inner blocks.
02000	   
02100	   
02200	3-31.    Arrays  declared  in  the  outer  block  must  have constant
02300	bounds, since no variable may yet have been assigned a  value.   They
02400	are thus automatically made OWN.
02500	   
02600	   
02700	3-32.    For more details concerning the internal structure of Arrays
02800	see DEBUGGING, 15-9, Separately Compiled Procedures, 16-7  and  ARRAY
02900	IMPLEMENTATION, 17-35.
03000	   
03100	   
03200	Preload Specifications
03300	   
03400	   
03500	3-33.    Any  OWN arithmetic or String Array may be "pre-loaded" with
03600	constant  information   by   preceding   its   declaration   with   a
03700	<preload_specification>.   This  specification gives the values which
03800	are to be placed in consecutive  core  locations  within  all  Arrays
03900	declared    immediately    following   the   <preload_specification>.
04000	"Immediately",  in  this  case,  means  all  identifiers  up  to  and
04100	including one which is followed by bound_pair_list brackets (e.g.  in
04200	REAL ARRAY X,Y,Z[0:10],W[1:5]; -- preloads X,Y, and Z; not W).  It is
04300	the user's responsibility to guarantee that the proper values will be
04400	obtained under the subscript mapping.
04500	   
04600	   
04700	3-34.    The original values of pre-loaded Arrays will not be lost by
04800	restarting   the   program   (most  Arrays  are  cleared  when  their
04900	declarations are processed), but  they  will  not  be  re-initialized
05000	either.  The values can be changed by assignment statements.
     

00100	SAILON NO. 57.2					SAIL   3-35
00200	
00300	   
00400	   
00500	3-35.    For  String Arrays, the original pre-loaded values remain if
00600	not changed by assignment statements.  In  general,  however,  String
00700	Array   elements  whose  values  have  been  changed  during  program
00800	executions will be set to null strings when the program is restarted.
00900	   
01000	   
01100	3-36.    Algebraic type conversions will be performed at compile-time
01200	to  provide  values  of  the  proper types to pre-loaded Arrays.  All
01300	expressions in these specifications must be constant  expressions  --
01400	that  is,  they  must contain only constants and algebraic operators.
01500	The compiler will not allow you to fill an Array beyond its capacity.
01600	You  may,  however,  provide a number of elements less than the total
01700	size of the Array; remaining elements will be set to zero or  to  the
01800	null string.
01900	   
02000	   
02100	Example
02200	   
02300	   
02400	3-37.    
02500	
02600	
02700	  PRELOAD_WITH [5] 0, 3, 4, [4] 6, 2;
02800	  INTEGER ARRAY TABL[1:4,1:3];
02900	
03000	The  first  five elements of TABL will be initialized to 0 (bracketed
03100	number is used as a repeat argument).  The next two elements will  be
03200	3  and  4,  followed  by  four 6's and a 2.  The array will look like
03300	this:
03400	
03500	
03600	        1  2  3
03700	
03800	    1   0  0  0
03900	    2   0  0  3
04000	    3   4  6  6
04100	    4   6  6  2
04200	
     

00100	SAILON NO. 57.2					SAIL   3-38
00200	
00300	   
00400	   
00500	Procedure Declarations
00600	   
00700	   
00800	3-38.    If a Procedure is typed, it may return a value  (see  Return
00900	Statement,  5-20)  of  the  specified type.  If formal parameters are
01000	specified, they must be supplied with actual parameters in a  one  to
01100	one  correspondence  when  they are called (see Function Designators,
01200	9-47 and Procedure Statements, 6-2).
01300	   
01400	   
01500	Formal Parameters
01600	   
01700	   
01800	3-39.    Formal parameters, when specified,  provide  information  to
01900	the  body  (executable  portion)  of the Procedure about the kinds of
02000	values which will be provided as actual parameters in the call.   The
02100	type  and  complexity  (simple  or  Array)  are  specified  here.  In
02200	addition, the formal parameter indicates whether the value (VALUE) or
02300	address (REFERENCE) of the actual parameter will be supplied.  If the
02400	address is supplied, the variable whose  identifier  is  given  as  an
02500	actual  parameter  may  be changed by the Procedure.  This is not the
02600	case if the value is given.
02700	   
02800	   
02900	3-40.    To pass a PROCEDURE by value or an ITEM by reference has  no
03000	readily  determined  meaning.   ARRAYs  passed  by value (requiring a
03100	complete copy operation) have not yet  been  implemented.   Therefore
03200	these cases are noted as errors by the compiler.
03300	   
03400	   
03500	3-41.    The  proper use of actual parameters is further discussed in
03600	the paragraphs on Procedure Statements, 6-2 and Function Designators,
03700	9-47.
     

00100	SAILON NO. 57.2					SAIL   3-42
00200	
00300	   
00400	   
00500	Forward Procedure Declarations
00600	   
00700	   
00800	3-42.    A  Procedure's  type and parameters must be described before
00900	the Procedure may  be  called.   Normally  this  is  accomplished  by
01000	specifying  the  procedure  declaration  in  the  head  of some block
01100	containing the call.  If,  however,  it  is  necessary  to  have  two
01200	Procedures, declared in some block head, which are both accessible to
01300	statements in the compound tail of that block and to each other,  the
01400	FORWARD construct permits the definition of the parameter information
01500	for one of these Procedures  in  advance  of  its  declaration.   The
01600	Procedure  body  must  be  empty  in a forward procedure declaration.
01700	When the body of the Procedure described in the  forward  declaration
01800	is  actually  declared,  the  types  of  the  Procedure  and  of  its
01900	parameters must be identical in both declarations.  The  declarations
02000	must appear at the same level (within the same block head).
     

00100	SAILON NO. 57.2					SAIL   3-43
00200	
00300	   
00400	   
00500	Example
00600	   
00700	   
00800	3-43.    
00900	   
01000	BEGIN "NEED FORWARD"
01100	   FORWARD INTEGER PROCEDURE T1(INTEGER I); COMMENT PARAMS DESCRIBED;
01200	   
01300	   INTEGER PROCEDURE T2(INTEGER J);
01400	       RETURN (T1(J)+3); COMMENT CALL T1 ;
01500	   
01600	   INTEGER PROCEDURE T1 (INTEGER I); COMMENT ACTUALLY DEFINE T1;
01700	       RETURN (IF I=15 THEN I ELSE T2(I-1)); COMMENT CALLS T2;
01800	   
01900	...
02000	   
02100	K←T1(L); ...  ; L←T2(K); ...
02200	   
02300	END "NEED FORWARD";
02400	   
02500	Notice that the forward declaration is  required  only  because  BOTH
02600	Procedures  are  called  in  the body of the block.  These procedures
02700	should also be declared RECURSIVE if recursive  entrance  is  likely.
02800	If only T1 were called from statements within the block, this example
02900	could be implemented as:
03000	   
03100	BEGIN "NO FORWARD"
03200	   RECURSIVE INTEGER PROCEDURE T1(INTEGER I);
03300	   BEGIN
03400	       INTEGER PROCEDURE T2(J);
03500	           RETURN (T1(J)+3);
03600	   
03700	       RETURN( IF I=15 THEN I ELSE T2(I-1));
03800	   END "T1";
03900	   
04000	...
04100	   K←T1(L);
04200	...
04300	END "NO FORWARD";
04400	   
     

00100	SAILON NO. 57.2					SAIL   3-44
00200	
00300	   
00400	   
00500	Recursive Procedures
00600	   
00700	   
00800	3-44.    If a Procedure is to be entered  recursively,  the  compiler
00900	must  be  instructed  to  provide code for saving its local variables
01000	when the Procedure is called and restoring them when it returns.  Use
01100	the  type-qualifier  RECURSIVE  in  the  declaration of any recursive
01200	Procedure.
01300	   
01400	   
01500	3-45.    The compiler  can  produce  much  more  efficient  code  for
01600	non-recursive  Procedures than for recursive ones.  We feel that this
01700	gain in efficiency merits the necessity for declaring  Procedures  to
01800	be recursive.
01900	   
02000	   
02100	3-46.    If  a  Procedure  which  has  not been declared recursive is
02200	called recursively, all its local variables  (and  temporary  storage
02300	locations  assigned  by  the  compiler)  will  behave as if they were
02400	global to the Procedure -- no values will be saved.  Otherwise no ill
02500	effects should be observed.
02600	   
02700	   
02800	External Procedures
02900	   
03000	   
03100	3-47.    A  file  compiled by SAIL represents either a "main" program
03200	or a collection of independent procedures to be called  by  the  main
03300	program.  The method for preparing such a collection of Procedures is
03400	described in Separately Compiled Procedures, 16-7.  The EXTERNAL  and
03500	FORTRAN  type-qualifiers  allow  description  of  the  types of these
03600	Procedures and their parameters.  An EXTERNAL  or  FORTRAN  procedure
03700	declaration,  like  the  FORWARD  declaration,  does  not  include  a
03800	procedure body.  Both declarations instead result in requests to  the
03900	loader to provide the addresses of these Procedures to all statements
04000	which call them.  This means that an EXTERNAL  Procedure  declaration
04100	(or  the declaration of any External identifier) may be placed within
04200	any block head,  thereby  controlling  the  scope  of  this  External
04300	identifier within this program.
04400	   
04500	   
04600	3-48.    Any  SAIL  Procedure  which is referenced via these external
04700	declarations  must  be  an  INTERNAL   Procedure.    That   is,   the
04800	type-qualifier  INTERNAL must appear in the actual declaration of the
04900	Procedure.  Again, see Separately Compiled Procedures, 16-7.
     

00100	SAILON NO. 57.2					SAIL   3-49
00200	
00300	   
00400	   
00500	3-49.    The type-qualifier FORTRAN is used to describe the type  and
00600	name  of  an  external  Procedure  which  is to be called using a DEC
00700	Fortran calling sequence.  All parameters to Fortran  Procedures  are
00800	by  reference.   In  fact, the procedure head part of the declaration
00900	need not be included unless  the  types  expected  by  the  Procedure
01000	differ  from  those  provided by the actual parameters--the number of
01100	parameters supplied, and their types, are presumed correct.   Fortran
01200	Procedures  are  automatically External Procedures.  See Restrictions
01300	on Procedure Declarations, 3-54, Procedure Statements, 6-2,  Function
01400	Designators, 9-47 for more information about Fortran Procedures.
01500	   
01600	   
01700	Example:
01800	   
01900	   
02000	3-50.    
02100	FORTRAN PROCEDURE MAX;
02200	Y←MAX(X,Z);
02300	   
02400	   
02500	Parametric Procedures
02600	   
02700	   
02800	3-51.    The  calling  conventions  for Procedures with Procedures as
02900	arguments, and for the execution of these parametric Procedures,  are
03000	described  in  Procedure  Statements,  6-2  and Function Designators,
03100	9-47.  Any Procedure PP which is to be used as a parameter to another
03200	Procedure  CP must not have any Procedure or array parameters, or any
03300	parameters called by value.  In other words, PP may only have  simple
03400	reference parameters.  The number of parameters supplied in a call on
03500	PP within CP, and their types, will be presumed correct.
     

00100	SAILON NO. 57.2					SAIL   3-52
00200	
00300	   
00400	   
00500	Example
00600	   
00700	   
00800	3-52.    
00900	
01000	PROCEDURE CP (INTEGER PROCEDURE FP);
01100	BEGIN INTEGER A,I; REAL X;
01200	 ...
01300	 A←FP(I,X); COMMENT I AND X PASSED BY REFERENCE,
01400		    NO TYPE CONVERSION;
01500	END "CP";
01600	
01700	INTEGER PROCEDURE PP (REFERENCE INTEGER J; REFERENCE REAL Y);
01800	BEGIN
01900	 ...
02000	END "PP";
02100	
02200	...
02300	
02400	CP(PP);
02500	
02600	   
02700	   
02800	Defaults in Procedure Declarations
02900	   
03000	   
03100	3-53.    If no  VALUE  or  REFERENCE  qualification  appears  in  the
03200	description, the following qualifications are assumed:
03300	                  
03400	
03500	VALUE          Variables -- simple  INTEGER,  STRING,  ITEM,  ITEMVAR
03600	               declarations.
03700	
03800	REFERENCE      Arrays and Procedures.
03900	   
04000	   
04100	Restrictions on Procedure Declarations
04200	   
04300	   
04400	3-54.    
04500	
04600	1)  The scope of a formal  parameter  for  a  Procedure  P  does  not
04700	    include  statements within any Procedure Q declared within P.  In
04800	    other words, Q may refer only to its own formal  parameters.   It
04900	    may,  however,  refer to variables which are local to some global
05000	    Procedure.  Here is an example:
     

00100	SAILON NO. 57.2					SAIL   3-54
00200	
00300	
00400	
00500	PROCEDURE P1(INTEGER I);
00600	BEGIN INTEGER J;
00700	 PROCEDURE P2(INTEGER K);
00800	 BEGIN
00900	  INTEGER L;
01000	  L←I; COMMENT THIS IS WRONG -- WON'T WORK;
01100	  L←J; COMMENT THIS IS ALL RIGHT;
01200	  L←K; COMMENT CLEARLY ALL RIGHT;
01300	  ...
01400	
01500	
01600	2)  There is no such thing as an ITEM Procedure (use ITEMVAR).
01700	
01800	3)   Fortran  Procedures  can  not  handle  String,  Set,   or   Item
01900	    parameters.   Nor  can  a  Fortran  Procedure return any of these
02000	    types as a result.
02100	
02200	4)  Go To Statements appearing in  a  Procedure  body  may  not  name
02300	    statements outside that Procedure body as targets.
02400	
02500	5)  Labels may never be passed as arguments to Procedures.
02600	   
02700	   
02800	Synonyms
02900	   
03000	   
03100	3-55.    The declaration `LET BEG=BEGIN' would tell the compiler that
03200	BEG is now a reserved word with the same meaning as BEGIN.  BEGIN can
03300	subsequently  be  DEFINEd  or  declared  as  something  else  without
03400	eliminating  the  opening  of  new  blocks (use BEG for BEGIN).  This
03500	synonymity applies only over the scope of the declaration, as usual.
03600	   
03700	   
03800	Define Specification
03900	   
04000	   
04100	3-56.    See the section on  USE  OF  DEFINE,  13-0  for  a  complete
04200	discussion.
04300	   
04400	   
04500	Requirements
04600	   
04700	   
04800	3-57.    The  user  may,  using the REQUIRE construct, specify to the
04900	compiler  conditions  which  are  required  to   be   true   of   the
05000	execution-time  environment  of  his programs.  The requirements fall
05100	into two classifications, described as follows:
     

00100	SAILON NO. 57.2					SAIL   3-57
00200	
00300	   
00400	   
00500	Group 1 -- Space requirements -- STRING_SPACE, SYSTEM_PDL, etc.
00600	   
00700	   
00800	3-58.    The   inclusion   of   the   specification   "REQUIRE   1000
00900	STRING_SPACE" will ensure that at least 1000 words of storage will be
01000	available for storing Strings  when  the  program  is  run.   Similar
01100	provisions  are  made  for  various  push-down  stacks  used  by  the
01200	execution-time routines and the compiled code.   If  a  parameter  is
01300	specified twice, or if separately compiled procedures are loaded (see
01400	Separately  Compiled  Procedures,  16-7),  the  sum   of   all   such
01500	specifications will be used.  These parameters could also be typed to
01600	the loaded program just before  execution  (see  STORAGE  ALLOCATION,
01700	14-22),  but  it is often more convenient to specify differences from
01800	the standard sizes in the source program.  Use  these  specifications
01900	only  if messages from the running program indicate that the standard
02000	allocations are not sufficient.  "REQUIRE  300  NEW_ITEMS"  specifies
02100	that  300  is a reasonable estimate of the number of items which will
02200	be created dynamically using the NEW construct.  "REQUIRE 100 PNAMES"
02300	will  allow up to 100 print names to be dynamically assigned to items
02400	(see New_Pname, 12-88, Cvis, 12-84 and following).   PNAMES  are  not
02500	available at all unless some number are "REQUIREd".
02600	   
02700	   
02800	Group 2 -- Other files -- LOAD_MODULE, LIBRARY, SOURCE_FILE, etc.
02900	   
03000	   
03100	3-59.        The    inclusion    of    the    specification
03200	REQUIRE "PROCS1" LOAD_MODULE, "HELIB[1,3]" LIBRARY; would inform  the
03300	Loader  that  the  file  PROCS1.REL  must  be  loaded and the library
03400	HELIB.REL[1,3]  searched  whenever   the   program   containing   the
03500	specification is loaded.  The parameter for both features should be a
03600	string constant of one of the above forms.  The device DSK, and  file
03700	extension  .REL  are the only values permitted for these entries, and
03800	are therefore assumed.
03900	   
04000	   
04100	3-60.    LOAD_MODULES  (.REL  files  to  be  loaded)  may  themselves
04200	contain  requests  for other LOAD_MODULES and LIBRARYs.  LIBRARYs may
04300	only contain requests for other LIBRARYs.   Duplicate  specifications
04400	are  in  general  merged into single requests (if a file is requested
04500	twice, it will be loaded only once).
04600	   
04700	   
04800	3-61.    SAIL  automatically  places  a  request  for   the   library
04900	"LIBSAI[1,3]"  in  each  main  program.   This  library  contains the
05000	execution-time routines.
     

00100	SAILON NO. 57.2					SAIL   3-62
00200	
00300	   
00400	   
00500	3-62.    The inclusion of  REQUIRE "SYS:PREAMB.SAI" SOURCE_FILE  (or,
00600	perhaps,  ... "PREAMB.SAI[1,3]" ...)  will cause the compiler to save
00700	the state of the current input file, then begin scanning from PREAMB.
00800	When PREAMB is exhausted, SAIL will resume scanning the original file
00900	on the line directly following  the  REQUIRE.   SOURCE_FILEs  may  be
01000	nested to a depth of about 10 levels.
01100	   
01200	   
01300	3-63.    Restrictions:  A  SOURCE_FILE  request must be followed by a
01400	semicolon (only one per REQUIREment), and must be the  last  text  on
01500	the  line  in  which  it  appears.  SOURCE_FILE switching must not be
01600	specified from within a DEFINE body.
01700	   
01800	   
01900	3-64.    The SEGMENT_NAME, SEGMENT_FILE specifications are  currently
02000	applicable  only  to the Stanford "global model" users of SAIL.  They
02100	allow specification of the name of a  special  non-sharable  "HISEG",
02200	and  the  name  of  the  file  used  to  create  this  HISEG.   These
02300	specifications may, like the space  REQUIREments,  be  overridden  by
02400	using the system REENTER command (see STORAGE ALLOCATION, 14-22).
02500	   
02600	   
02700	Comment
02800	   
02900	   
03000	3-65.    You  have  probably  noticed  that  a  great  deal  of prior
03100	knowledge is required for proper understanding of this section.   For
03200	more information about PNAMES see Cvis, 12-84 and following.  Storage
03300	allocation is discussed in STORAGE ALLOCATION, 14-22 below.  The form
03400	and  use  of  .REL files and libraries are described in "The Stanford
03500	A-I Project Monitor Manual" [Moorer] and [Weiher].
     

00100	SAILON NO. 57.2					SAIL   4-1
00200	
00300	                              SECTION 4
00400	                                    
00500	                        ASSIGNMENT STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	4-1.    
01300	
01400	<assignment>             ::= <assignment_statement>
01500	                         ::= <swap_statement> 
01600	
01700	<assignment_statement>   ::= <algebraic_assignment>
01800	                         ::= <item_assignment>
01900	                         ::= <set_assignment> 
02000	
02100	<algebraic_assignment>   ::= <algebraic_variable> ← 
02200	                                <algebraic_expression> 
02300	
02400	<item_assignment>        ::= <itemvar_variable> ← 
02500	                                <construction_item_expression> 
02600	
02700	<set_assignment>         ::= <set_variable> ← 
02800	                                <construction_set_expression> 
02900	   
03000	   
03100	
03200	<swap_statement>         ::= <variable> ↔ <variable> 
03300	   
03400	   
03500	
03600	<byte_statement>         ::= DPB (algebraic_expression , 
03700	                                <algebraic_expression> )
03800	                         ::= IDPB (algebraic_expression , 
03900	                                <algebraic_variable> )
04000	                         ::= IBP (algebraic_variable) 
04100	   
04200	   
04300	   
04400	RESTRICTION
04500	   
04600	   
04700	4-2.    If the operator is ↔, the expression (of  whatever  kind)  on
04800	the  right  hand  side  must  be a simple or subscripted variable, or
04900	DATUM(<item_primary>).   The  ↔  operator  may  not  be  used  in  an
05000	assignment expression (see Assignment Expressions, 9-4).  It is valid
05100	only at statement level.
     

00100	SAILON NO. 57.2					SAIL   4-2
00200	
00300	   
00400	   
00500	SEMANTICS
00600	   
00700	   
00800	4-3.    The assignment statement causes the value represented  by  an
00900	expression  to  be  assigned to the variable appearing to the left of
01000	the  assignment  symbol.   You  will  see   later   (see   Assignment
01100	Expressions,  9-4)  that  one  value  may  be assigned to two or more
01200	variables through the use of two or  more  assignment  symbols.   The
01300	operation  of  the  assignment  statement  proceeds  in the following
01400	order:
01500	
01600	a)     The subscript expressions of the  left  part  variable  (if
01700	       any)  are  evaluated  from  left  to  right (see Expression
01800	       Evaluation Rules, 9-14).
01900	
02000	b)     The expression is evaluated.
02100	
02200	c)     The value of the expression is assigned to  the  left  part
02300	       variable, with subscript expressions, if any, having values
02400	       as determined in step a.
02500	   
02600	   
02700	4-4.    This ordering  of  operations  may  usually  be  disregarded.
02800	However  it becomes important when expression assignments (Assignment
02900	Expressions, 9-4) or function calls with reference parameters  appear
03000	anywhere in the statement.  For example, in the statements
03100	   
03200	    I←3;
03300	    A[I]←3+(I←1);
03400	   
03500	A[3]  will  receive  the  value  4  using the above algorithm.  If no
03600	subscript calculations were  performed  until  after  the  expression
03700	evaluation, A[1] would become 4.  Be careful.
03800	   
03900	   
04000	4-5.    As  the  syntax implies, if the left part variable is of type
04100	Itemvar the  value  to  be  assigned  must  be  a  construction  Item
04200	expression.  Similarly for Sets.
04300	   
04400	   
04500	4-6.    However,  any  algebraic expression (REAL, INTEGER (BOOLEAN),
04600	or STRING) may be assigned to any variable of  algebraic  type.   The
04700	resultant  type  will  be  that  of  the  left  part  variable.   The
04800	conversion rules for assignments involving  mixed  types  are  mildly
04900	amusing.   They  are  identical to the conversion rules for combining
05000	mixed types in algebraic expressions (see Arithmetic Type Conversions,
05100	9-21, String-Arithmetic Conversions, 9-27 below).
     

00100	SAILON NO. 57.2					SAIL   4-6
00200	
00300	   
00400	   
00500	Datum Assignments
00600	   
00700	   
00800	4-7.    The algebraic or Set value associated with an Item is changed
00900	using an assignment statement in which the left part is  a  the  word
01000	DATUM  operating  on  an  Item  Primary.  This is valid syntactically
01100	because the syntax for <variable> (see Variables, 11-2) includes this
01200	DATUM  construct.   The expression is checked for validity and proper
01300	type conversions are made before this  kind  of  store  occurs.   One
01400	hazard  is  that there are times when the compiler cannot verify that
01500	an Item assigned to an Itemvar has a datum whose  type  matches  that
01600	expected by the Itemvar.  Incorrect conversions might well be made in
01700	this case.
01800	   
01900	   
02000	Swap Assignment
02100	   
02200	   
02300	4-8.    The ↔ operator causes the value of the variable on  the  left
02400	hand side to be exchanged with the value of the variable on the right
02500	hand side.  Arithmetic (REAL↔INTEGER) type conversions are  made,  if
02600	necessary;  any  other type conversions are invalid.  Remember, the ↔
02700	operator may not be used in assignment expressions.
02800	   
02900	   
03000	Examples
03100	   
03200	   
03300	4-9.    
03400	
03500	  X←I←A+B; Comment if A, B and X are Real, I Integer,
03600	                the Real value of the  sum is truncated,
03700	                converted to an Integer, and stored in I. 
03800			The truncated value is then converted to 
03900			a Real number and stored in X.
04000	
04100	  BEGIN REAL ITEMVAR X;
04200	    X←LOP(SET3);
04300	    DATUM(X) ← 5; Comment a  conversion  to 5.0  will be made
04400		before the store  is done,  but there is no guarantee
04500		that the Item obtained by LOP(SET3) was not declared,
04600		for example, as INTEGER ITEM A;
04700	  END;
04800	
     

00100	SAILON NO. 57.2					SAIL   4-10
00200	
00300	   
00400	   
00500	Byte statements
00600	   
00700	   
00800	4-10.    
00900	   
01000	   
01100	4-10.    The  statements  DPB,  IDPB  and  IBP   are   provided   for
01200	manipulating  bytes  of  information.   These  operations  correspond
01300	exactly to the PDP-10 machine instructions  for  manipulating  bytes.
01400	The formats are as follows:
01500	
01600	   1)  DPB ( byte, byte_pointer )
01700	       The "byte" is deposited according to the byte_pointer.  The
01800	       POINT  procedure  may  be used for generating byte pointers
01900	       (see Point, 12-126).
02000	
02100	   2)  IDPB ( byte, byte_pointer )
02200	       The "byte" is deposited, and the byte_pointer  incremented.
02300	       For this reason, the byte_pointer may not be an expression,
02400	       but must be a variable.
02500	
02600	   3)  IBP ( byte_pointer )
02700	       The byte_pointer is incremented.  The rules for IDPB apply.
02800	   
     

00100	SAILON NO. 57.2					SAIL   5-1
00200	
00300	                              SECTION 5
00400	                                    
00500	                     EXECUTION CONTROL STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	5-1.    
01300	
01400	<conditional_statement>  ::= <if_statement>
01500	                         ::= <if_statement> ELSE <statement> 
01600	
01700	<if_statement>           ::= IF <boolean_expression> THEN <statement> 
01800	   
01900	   
02000	
02100	<go_to_statement>        ::= GO TO <label_identifier>
02200	                         ::= GOTO <label_identifier>
02300	                         ::= GO <label_identifier> 
02400	
02500	<label_identifier>       ::= <identifier> 
02600	   
02700	   
02800	
02900	<for_statement>          ::= FOR <algebraic_variable> ← <for_list> DO 
03000	                                <statement>
03100	                         ::= NEEDNEXT <for_statement> 
03200	
03300	<for_list>               ::= <for_list_element>
03400	                         ::= <for_list> , <for_list_element> 
03500	
03600	<for_list_element>       ::= <algebraic_expression>
03700	                         ::= <algebraic_expression> STEP 
03800	                                <algebraic_expression> UNTIL 
03900	                                <algebraic_expression>
04000	                         ::= <algebraic_expression> STEP 
04100	                                <algebraic_expression> WHILE 
04200	                                <boolean_expression> 
04300	   
04400	   
04500	
04600	<while_statement>        ::= WHILE <boolean_expression> DO <statement>
04700	                         ::= NEEDNEXT <while_statement> 
04800	   
04900	   
     

00100	SAILON NO. 57.2					SAIL   5-1
00200	
00300	
00400	<do_statement>           ::= DO <statement> UNTIL <boolean_expression>
00500	                         ::= NEEDNEXT <do_statement> 
00600	   
00700	   
00800	
00900	<case_statement>         ::= <case_statement_head> <compound_tail> 
01000	
01100	<case_statement_head>    ::= CASE <algebraic_expression> OF BEGIN 
01200	   
01300	   
01400	
01500	<return_statement>       ::= RETURN
01600	                         ::= RETURN ( <expression> ) 
01700	
01800	<done_statement>         ::= DONE
01900	                         ::= DONE <block_name> 
02000	
02100	<next_statement>         ::= NEXT
02200	                         ::= NEXT <block_name> 
02300	
02400	<continue_statement>     ::= CONTINUE
02500	                         ::= CONTINUE <block_name> 
02600	   
02700	   
02800	   
02900	SEMANTICS
03000	   
03100	Conditional Statements
03200	   
03300	   
03400	5-2.    These statements provide a means whereby the execution  of  a
03500	statement,  or  a  series  of statements, is dependent on the logical
03600	value produced by a Boolean expression.
03700	   
03800	   
03900	5-3.    A Boolean expression is an  algebraic  expression  whose  use
04000	implies  that  it  is  to  be tested as a logical (truth) value.  The
04100	rules for determining this value are given in Simple Expressions, 9-9
04200	and following.
04300	   
04400	   
04500	If Statement
04600	   
04700	   
04800	5-4.    The statement following the operator THEN (the "THEN part") is
04900	executed if the logical value of  the  Boolean  expression  is  TRUE;
05000	otherwise, that statement is ignored.
     

00100	SAILON NO. 57.2					SAIL   5-4
00200	
00300	   
00400	   
00500	If ...  Else Statement
00600	   
00700	   
00800	5-5.    If the Boolean expression is true, the "THEN part" is executed
00900	and the statement following the operator ELSE (the  "ELSE  part")  is
01000	ignored.   If  the  Boolean  expression  is  FALSE, the "ELSE part" is
01100	executed and the "THEN part" is ignored.
01200	   
01300	   
01400	Ambiguity in Conditional Statements
01500	   
01600	   
01700	5-6.    The syntax given here for  conditional  statements  does  not
01800	fully  explain  the  correspondences  between  THEN-ELSE  pairs  when
01900	conditional statements are nested.  An ELSE  will  be  understood  to
02000	match the immediately preceding unmatched THEN.
02100	   
02200	   
02300	Example
02400	   
02500	   
02600	5-7.    
02700	
02800	COMMENT DECIDE WHETHER TO GO TO WORK;
02900	
03000	IF ¬WEEKEND THEN
03100	    IF GIANTS_ON_TV THEN BEGIN
03200		PHONE_EXCUSE("GRANDMOTHER DIED");
03300		ENJOY(GAME);
03400		SUFFER(CONSCIENCE_PANGS)
03500	    END
03600	    ELSE IF REALLY_SICK THEN BEGIN
03700		PHONE_EXCUSE("REALLY SICK");
03800		ENJOY(0);
03900		SUFFER(AGONY)
04000	    END
04100	    ELSE GO TO WORK;
04200	
     

00100	SAILON NO. 57.2					SAIL   5-8
00200	
00300	   
00400	   
00500	Go To Statements
00600	   
00700	   
00800	5-8.    Each of the three forms of the Go To statement means the same
00900	thing -- an unconditional transfer is to  be  made  to  the  "target"
01000	statement  labeled  by  the  label  identifier.   The following rules
01100	pertain to labels:
01200	
01300	1)  All label identifiers used in a program must be declared.  The
01400	    declaration  of a label must be local to the block immediately
01500	    surrounding the statement it identifies (see exception below).
01600	    Note  that  compound statements (BEGIN-END pairs containing no
01700	    declarations) are not blocks.  Therefore the block
01800	
01900	
02000		BEGIN "B1"
02100		 INTEGER I,J; LABEL L1;
02200		 ...
02300		 IF BE3 THEN BEGIN "C1"
02400		  ...
02500		  L1:  ...
02600		  ...
02700		 END "C1";
02800		 ...
02900		 GO TO L1
03000		END "B1"
03100	
03200		   is legal.
03300	
03400	2)  No Go To Statement may specify a transfer from a statement  S1
03500	    outside  a  given  block  to a target statement S2 inside that
03600	    block, if the block contains any Array declarations.  This  is
03700	    automatic  from  rule 1, since the label identifying S2 is not
03800	    available to S1.  When  no  Array  declarations  are  present,
03900	    access  may  be  provided by moving the label declaration into
04000	    blocks global to the block containing the labelled  statement,
04100	    as  long as the declaration is not made global to a block with
04200	    Array declarations, and rule 4 below is followed.   Again  the
04300	    rule  does  not  apply  to  compound  statements, as the above
04400	    example demonstrates.
04500	
04600	3)  No Go To statement may specify a  transfer  from  a  statement
04700	    within  a Procedure to a statement outside that Procedure (you
04800	    can't jump out of Procedures).
04900	
05000	4)  No Go To statement may  specify  a  transfer  into  a  FOREACH
05100	    statement, or into complicated For loops (those with For Lists
     

00100	SAILON NO. 57.2					SAIL   5-8
00200	
00300	    or which contain a NEXT statement).
00400	   
00500	   
00600	5-9.    Labels will seldom be needed  for  debugging  purposes.   The
00700	block  name  feature  (see  DEBUGGING,  15-9) and the listing feature
00800	which associates with each source  line  the  octal  address  of  its
00900	corresponding  object  code  (see  Listing  Features,  14-13)  should
01000	provide enough information to find things easily.
01100	   
01200	   
01300	5-10.    Many program loops coded with labels  can  be  alternatively
01400	expressed  as  For  or  While  loops,  augmented  by  DONE, NEXT, and
01500	CONTINUE statements.  This often results in a  source  program  whose
01600	organization  is  somewhat  more  transparent,  and an object program
01700	which is more efficient.
01800	   
01900	   
02000	For Statements
02100	   
02200	   
02300	5-11.    For and While statements (see also FOREACH Statement,  7-15)
02400	provide  methods  for  forming  loops  in  a program.  They allow the
02500	repetitive execution of  a  statement  zero  or  more  times.   These
02600	statements  will  be  described  by  means of SAIL programs which are
02700	functionally equivalent but which demonstrate better the actual order
02800	of  processing.  Refer to these equations for any questions you might
02900	have about what gets evaluated when, and how many times each part  is
03000	evaluated.
03100	   
03200	   
03300	5-12.    Let  VBL  be  any  algebraic  variable,  AE1, ...  , AE8 any
03400	algebraic expressions, BE  a  Boolean  expression,  TEMP  a  temporary
03500	location,  S  a  statement.   Then  the following SAIL statements are
03600	equivalent:
03700	
03800	
03900	Using For Statements -- 
04000	
04100	    FOR VBL ← AE1, AE2, AE3 STEP AE4 UNTIL AE5,
04200		AE6 STEP AE7 WHILE BE, AE8 DO S;
04300	
04400	
04500	Equivalent formulation without For Statements --
04600	
04700	    VBL←AE1;
04800	    S;
04900	    VBL←AE2;
05000	    S;
05100	
     

00100	SAILON NO. 57.2					SAIL   5-12
00200	
00300	
00400	  Comment STEP-UNTIL loop;
00500	    VBL←AE3;
00600	LOOP1: 
00700	    IF (VBL-AE5) * SIGN(AE4) ≤ 0 THEN
00800	    BEGIN
00900		S;
01000		VBL←VBL+AE4;
01100		GO TO LOOP1
01200	    END;
01300	
01400	
01500	  Comment STEP-WHILE loop;
01600	    VBL←AE6;
01700	LOOP2:
01800	    IF BE THEN BEGIN
01900		S;
02000		VBL←VBL+AE7;
02100		GO TO LOOP2
02200	    END;
02300	
02400	    VBL←AE8;
02500	    S;
02600	
02700	If AE4 (AE7) is an unsubscripted variable, changing its value  within
02800	the  loop will cause the new value to be used for the next iteration.
02900	If AE4 (AE7) is a constant or an expression requiring  evaluation  of
03000	some  operator,  the  value  used  for  the  step element will remain
03100	constant throughout the execution of the For Statement.  If AE5 is an
03200	expression, it will be re-evaluated before each iteration.
03300	   
03400	   
03500	5-13.    Now consider the For Statement:
03600	
03700	    FOR VBL←AE1 STEP CONST UNTIL AE2 DO S;
03800	
03900	where  const is a positive constant.  The compiler will simplify this
04000	case to:
04100	
04200	
04300	    VBL←AE1;
04400	LOOP3: 
04500	    IF VBL ≤ AE2 THEN BEGIN
04600		S;
04700		VBL←VBL+CONST;
04800		GO TO LOOP3
04900	    END;
05000	
     

00100	SAILON NO. 57.2					SAIL   5-13
00200	
00300	If CONST is negative, the line at LOOP3 would be:
00400	
00500	
00600	LOOP3:
00700	    IF VBL ≥ AE2 THEN BEGIN
00800	
00900	   
01000	   
01100	5-14.    The value of VBL when execution of the loop  is  terminated,
01200	whether  it  be  by  exhaustion  of the for list or by execution of a
01300	DONE,NEXT  or  GO  TO  statement  (see  Done   Statement,   5-24,Next
01400	Statement, 5-26,Go To Statements, 5-8), is the value last assigned to
01500	it using  the  algorithm  above.   This  value  is  therefore  always
01600	well-defined.
01700	   
01800	   
01900	5-15.    The   statement  S  may  contain  assignment  statements  or
02000	procedure calls which change the value  of  VBL.   Such  a  statement
02100	behaves  the same way it would if inserted at the corresponding point
02200	in the equivalent loop described above.
02300	   
02400	   
02500	While Statement
02600	   
02700	   
02800	5-16.    The statement
02900	   
03000	    WHILE BE DO S;
03100	   
03200	is equivalent to the statements:
03300	
03400	LOOP:
03500	    IF BE THEN BEGIN
03600		S;
03700		GO TO LOOP
03800	    END;
     

00100	SAILON NO. 57.2					SAIL   5-17
00200	
00300	   
00400	   
00500	Do Statement
00600	   
00700	   
00800	5-17.    The statement
00900	   
01000	    DO S UNTIL BE;
01100	   
01200	is equivalent to the sequence:
01300	
01400	
01500	LOOP:
01600	    S;
01700	    IF ¬BE THEN GO TO LOOP;
01800	
01900	   
02000	   
02100	Case Statements
02200	   
02300	   
02400	5-18.    The statement
02500	
02600	CASE AE OF BEGIN
02700	    S0; S1; S2;... Sn 
02800	END
02900	
03000	is functionally equivalent to the statements:
03100	
03200	    TEMP←AE;
03300	    IF 		TEMP = 0 THEN S0
03400		ELSE IF TEMP = 1 THEN S1
03500		ELSE IF TEMP = 2 THEN S2
03600		...
03700		ELSE IF TEMP = n THEN Sn
03800	    ELSE ERROR;
03900	
04000	For applications of this type  the  CASE  statement  form  will  give
04100	significantly  more efficient code than the equivalent If statements.
04200	Notice that dummy statements may be inserted for  those  cases  which
04300	will not occur or for which no entries are necessary.  For example,
04400	
04500	
04600	CASE AE OF BEGIN
04700	    S0; ; ; S3; ; ; S6; END 
04800	
04900	provides  for  no actions when AE is 1,2,4,5, or 7.  When AE is 0, 3,
05000	or 6 the corresponding statement will be executed.
     

00100	SAILON NO. 57.2					SAIL   5-19
00200	
00300	   
00400	   
00500	5-19.    The CASE statement gives rise to one of the  few  legitimate
00600	uses  of SAIL Labels.  If two of the S[i] within a CASE are to do the
00700	same thing except for some initial statements, it is useful  to  jump
00800	from  one  into the other (or from both to an unused third) after the
00900	individual code has been executed.  If two of the S[i] are to provide
01000	exactly  the  same  functions,  it  is  better  to combine them via a
01100	mapping function on the CASE  index  (e.g.,  use  a  character  table
01200	containing  the  same CASE index for all characters which do the same
01300	thing).
01400	   
01500	   
01600	Return Statement
01700	   
01800	   
01900	5-20.    This statement is invalid if it appears outside a  procedure
02000	declaration.   It  provides  for  an  early  return  from a Procedure
02100	execution to the statement  calling  the  Procedure.   If  no  return
02200	statement  is  executed,  the  Procedure  will  return after the last
02300	statement representing the procedure body is executed (see  Procedure
02400	Declarations, 3-38).
02500	   
02600	   
02700	5-21.    An untyped Procedure (see Procedure Statements, 6-2) may not
02800	return a value.  The return statement  for  this  kind  of  Procedure
02900	consists merely of the word RETURN.  If an argument is given, it will
03000	cause the compiler to issue an error message.
03100	   
03200	   
03300	5-22.    A typed Procedure  (see  Function  Designators,  9-47)  must
03400	return  a value as it executes a return statement.  If no argument is
03500	present an error message will be given.   If  the  Procedure  has  an
03600	algebraic  type,  any  algebraic  expression  may  be returned as its
03700	value; type conversion will be performed in  a  manner  described  by
03800	Arithmetic  Type Conversions, 9-21 and String-Arithmetic Conversions,
03900	9-27 below.  If the Procedure is of type SET or  ITEM,  the  argument
04000	must be an expression of type SET or ITEM.
04100	   
04200	   
04300	5-23.    If no RETURN statement is executed in a typed Procedure, the
04400	value returned is undefined (it could be anything  --  try  it,  it's
04500	fun).
     

00100	SAILON NO. 57.2					SAIL   5-24
00200	
00300	   
00400	   
00500	Done Statement
00600	   
00700	   
00800	5-24.    The  statement  containing only the word DONE may be used to
00900	terminate the execution of a FOR, WHILE, or FOREACH loop  explicitly.
01000	Its  operation  can  most easily be seen by means of an example.  The
01100	statement
01200	
01300	
01400	    FOR I←1 STEP 1 UNTIL n DO BEGIN
01500		S;
01600		...
01700		IF BE THEN DONE;
01800		...
01900	    END
02000	
02100	    is equivalent to the statement
02200	
02300	    FOR I←1 STEP 1 UNTIL n DO BEGIN
02400		S;
02500		...
02600		IF BE THEN GO TO EXIT;
02700		...
02800	    END;
02900	EXIT:
03000	
03100	In either case the value of I is well-defined after the statement has
03200	been executed (see For Statements, 5-14).
03300	   
03400	   
03500	5-25.    The  DONE  statement  will  only  cause  an  escape from the
03600	innermost loop in which it  appears,  unless  a  block  name  follows
03700	"DONE".   The  block  name  must  be  the name of a block or compound
03800	statement (a "Loop Block") which is the object statement of some FOR,
03900	FOREACH,  WHILE,  or DO statement in which the current one is nested.
04000	The effect is to terminate all loops out to (and including) the  Loop
04100	Block, continuing with the statement following this outermost loop.
     

00100	SAILON NO. 57.2					SAIL   5-26
00200	
00300	   
00400	   
00500	Next Statement
00600	   
00700	   
00800	5-26.    A  Next  statement  is  valid only in a For Statement, While
00900	Statement, Do Statement, or Foreach Statement  (see  For  Statements,
01000	5-11,  etc.,  FOREACH  Statement,  7-15).   Processing  of  the  loop
01100	statement is temporarily suspended.  When the NEXT statement  appears
01200	in  a  For or Foreach loop, the next value (set of items) is obtained
01300	from  the  For  List  (Associative  Context)  and  assigned  to   the
01400	controlled  variable (bound variables).  The termination test is then
01500	made.  If the termination condition is satisfied, control  is  passed
01600	to  the  statement  following the For Statement or Foreach statement.
01700	If not, control is returned to the inner statement following the NEXT
01800	statement.   In  While  and  Do  loops,  the termination condition is
01900	tested.  If it  is  satisfied,  execution  of  the  loop  terminates.
02000	Otherwise  it  resumes at the statement within the loop following the
02100	NEXT statement.
02200	   
02300	   
02400	5-27.    Unless  a  block  name  follows  NEXT,  the  innermost  loop
02500	containing  the  NEXT  statement  is  used,  and  must be preceded by
02600	NEEDNEXT.  If a block name is present, the terminating condition  for
02700	the  loop  containing  the  "Loop  Block"  (see Done Statement, 5-24,
02800	above) is checked.  If the condition is  met,  all  inner  loops  are
02900	terminated  (in DONE fashion) as well.  If continuation is indicated,
03000	no inner-loop FOR-variable or WHILE-condition will have been affected
03100	by the NEXT code.  In complicated cases, many strange effects will be
03200	noticed.
03300	   
03400	   
03500	5-28.    The reserved word NEEDNEXT must precede FOREACH, FOR, WHILE,
03600	or DO in the "Loop Block", and must not appear between this block and
03700	the NEXT statement.
03800	   
03900	   
04000	Example
04100	   
04200	   
04300	5-29.    
04400	
04500	   NEEDNEXT WHILE ¬EOF DO BEGIN
04600		S←INPUT(1,1);
04700		NEXT;	Comment check EOF and terminate if TRUE;
04800		T←INPUT(1,3);
04900	        PROCESS_INPUT(S,T);
05000	   END;
05100	
     

00100	SAILON NO. 57.2					SAIL   5-29
00200	
00300	   
00400	   
00500	Continue Statement
00600	   
00700	   
00800	5-30.    The Continue statement is valid in only those contexts valid
00900	for  the  DONE statement (see Done Statement, 5-24); the "Loop Block"
01000	is determined in the same way.  All loops out to the Loop  Block  are
01100	terminated  as if DONE had been requested.  Control is transferred to
01200	a point inside the loop containing the  Loop  Block,  but  after  all
01300	statements in the loop.
01400	   
01500	   
01600	Example:
01700	   
01800	   
01900	5-31.    
02000	
02100		FOR I←1 STEP 1 UNTIL N DO BEGIN
02200			...
02300			CONTINUE;
02400			...
02500		END
02600	
02700	   is semantically equivalent to:
02800	
02900		FOR I←1 STEP 1 UNTIL N DO BEGIN
03000			LABEL CONT;
03100			...
03200			GO TO CONT;
03300			...
03400		 CONT:
03500		END
03600	
03700	   
     

00100	SAILON NO. 57.2					SAIL   6-1
00200	
00300	                              SECTION 6
00400	                                    
00500	                         PROCEDURE STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	6-1.    
01300	
01400	<procedure_statement>    ::= <procedure_identifier>
01500	                         ::= <procedure_identifier> ( 
01600	                                <actual_parameter_list> ) 
01700	
01800	<actual_parameter_list>  ::= <actual_parameter>
01900	                         ::= <actual_parameter_list> , 
02000	                                <actual_parameter> 
02100	
02200	<actual_parameter>       ::= <expression>
02300	                         ::= <array_identifier>
02400	                         ::= <procedure_identifier> 
02500	   
02600	   
02700	   
02800	SEMANTICS
02900	   
03000	   
03100	6-2.    A  Procedure  statement is used to invoke the execution of an
03200	untyped Procedure (see Procedure Declarations, 3-38).  It may also be
03300	used to supply parameters to the Procedure.
03400	   
03500	   
03600	6-3.    No  value  may  be  returned  from  a  Procedure  called by a
03700	Procedure statement, since there is no specification in the statement
03800	telling  how  to  use  the  value.   The  compiler  determines  how a
03900	Procedure may be used by noticing if a  type  was  specified  in  the
04000	procedure  declaration.   After  execution  of the Procedure, control
04100	returns  to  the  statement  immediately  following   the   Procedure
04200	statement.   However,  SAIL does allow you to use typed Procedures as
04300	procedure statements.  The  value  returned  from  the  Procedure  is
04400	simply discarded.
     

00100	SAILON NO. 57.2					SAIL   6-4
00200	
00300	   
00400	   
00500	Actual Parameters
00600	   
00700	   
00800	6-4.    The actual parameters supplied to a Procedure must in general
00900	match the formal parameters described in the  procedure  declaration.
01000	As  usual,  the  exception  is  algebraic  expressions;  the transfer
01100	functions  described  in  Arithmetic  Type  Conversions,   9-21   and
01200	String-Arithmetic  Conversions,  9-27  will be applied to convert the
01300	type of any algebraic expression passed by  VALUE  to  the  algebraic
01400	type required by the Procedure.
01500	   
01600	   
01700	Call by Value
01800	   
01900	   
02000	6-5.    If  an actual parameter is passed by VALUE, only the value of
02100	the expression is given to the Procedure.  This value may be  changed
02200	or  examined  by the Procedure, but this will in no way affect any of
02300	the variables used to evaluate the actual parameters.  Any  algebraic
02400	expression,  any  Item  or  Set  expression  may  be passed by value.
02500	Neither Arrays nor Procedures  may  be  passed  by  value.   See  the
02600	default   declarations   for  parameters  in  Defaults  in  Procedure
02700	Declarations, 3-53.
02800	   
02900	   
03000	Call by Reference
03100	   
03200	   
03300	6-6.    If an actual parameter is passed by REFERENCE, its address is
03400	passed  to the Procedure.  All accesses to the value of the parameter
03500	made by the Procedure  are  made  indirectly  through  this  address.
03600	Therefore  any  change  the  Procedure makes in a reference parameter
03700	will change the value of the variable which was  used  as  an  actual
03800	parameter.  This is sometimes useful.  However if it is not intended,
03900	use of this feature  can  also  be  somewhat  confusing  as  well  as
04000	moderately  inefficient.   Reference  parameters  should be used only
04100	where needed.
04200	   
04300	   
04400	6-7.    Variables,   constants,   Procedures,   Arrays,   and    most
04500	expressions  may  be  passed  by reference.  Neither Items nor String
04600	expressions (or String constants) may be reference parameters.
     

00100	SAILON NO. 57.2					SAIL   6-8
00200	
00300	   
00400	   
00500	6-8.    If an expression is passed by reference, its value  is  first
00600	placed  in  a  temporary  location; a constant passed by reference is
00700	stored in a unique location.  The address of this location is  passed
00800	to the Procedure.  Therefore, any values changed by the Procedure via
00900	reference parameters of this form will be  inaccessible  to  the  user
01000	after  the  Procedure  call.   If  the  called program is an assembly
01100	language routine which saves the parameter address, it  is  dangerous
01200	to  pass  expressions  to  it, since this address will be used by the
01300	compiler for other temporary purposes.  A  warning  message  will  be
01400	printed when expressions are called by reference.
01500	   
01600	   
01700	6-9.    The type of each actual parameter passed by reference must be
01800	identical  to  that  of  its  corresponding  formal  parameter.    An
01900	exception  is  made for Fortran calls (see Fortran Procedures, 6-12).
02000	If an algebraic type mismatch  occurs  the  compiler  will  create  a
02100	temporary  variable  containing  the  converted  value  and  pass the
02200	address of this temporary as the parameter.  A warning  message  will
02300	be printed.
02400	   
02500	   
02600	Procedures as Actual Parameters
02700	   
02800	   
02900	6-10.    If  an  actual  parameter to a Procedure PC is the name of a
03000	Procedure PR with no arguments, one of three things might happen:
03100	
03200	   1)  If the corresponding formal parameter requires a value of a
03300	       type matching that of PR (in the loose sense given above in
03400	       Actual Parameters, 6-4), the Procedure is evaluated and its
03500	       value is sent to the Procedure PC.
03600	
03700	   2)   If  the  formal  parameter  of  PC  requires  a  reference
03800	       Procedure of identical type, the address of PR is passed to
03900	       PC as the actual parameter.
04000	
04100	   3)  If the formal parameter requires a reference variable,  the
04200	       Procedure  is evaluated, its result stored, and its address
04300	       passed (as with expressions in the previous  paragraph)  as
04400	       the parameter.
     

00100	SAILON NO. 57.2					SAIL   6-11
00200	
00300	   
00400	   
00500	6-11.    If a Procedure name followed by actual parameters appears as
00600	an actual parameter it is evaluated (see Function Designators, 9-47).
00700	Then  if  the  corresponding  formal  parameter requires a value, the
00800	result of this evaluation is passed as the actual parameter.  If  the
00900	formal  parameter  requires a reference to a value, it is called as a
01000	reference expression.
01100	   
01200	   
01300	Fortran Procedures
01400	   
01500	   
01600	6-12.    If the Procedure being called is a  Fortran  Procedure,  all
01700	actual  parameters  must  be  of type INTEGER (BOOLEAN) or REAL.  All
01800	such parameters are passed by  reference,  since  Fortran  will  only
01900	accept   that  kind  of  call.   For  convenience,  any  constant  or
02000	expression used as an actual parameter  to  a  Fortran  Procedure  is
02100	stored  in  a  temporary cell whose address is given as the reference
02200	actual parameter.
02300	   
02400	   
02500	6-13.    It was explained in Procedure Declarations, 3-38 that formal
02600	parameters need not be described for Fortran Procedures.  This allows
02700	a program to  call  a  Fortran  Procedure  with  varying  numbers  of
02800	arguments, a feature which exists in DEC Fortran.  No type conversion
02900	will be performed for such parameters, of course.  If type conversion
03000	is  desired,  the formal parameter declarations should be included in
03100	the Fortran procedure declaration; SAIL will use  them  if  they  are
03200	present.
03300	   
03400	   
03500	6-14.    To  pass  an  Array  to  Fortran, mention the address of its
03600	first element (e.g.  A[0], or B[1,1]).
03700	   
03800	   
03900	Implementation Details
04000	   
04100	   
04200	6-15.    See the paragraphs concerning procedures in the  section  on
04300	implementation  (PROCEDURE IMPLEMENTATION, 17-48) for descriptions of
04400	the calling sequences and basic layout of SAIL procedures.  See  also
04500	Separately Compiled Procedures, 16-7 for more information about these
04600	useful constructs.
     

00100	SAILON NO. 57.2					SAIL   6-16
00200	
00300	   
00400	   
00500	Examples:
00600	   
00700	   
00800	6-16.    To call an untyped Procedure:
00900	
01000	BEGIN ...; PROC(I+J,A[Q],L); ...END;
01100	To call a Procedure of type Integer with one Integer argument:
01200	
01300	I←PROC(PROC(I));
01400	   
     

00100	SAILON NO. 57.2					SAIL   7-1
00200	
00300	                              SECTION 7
00400	                                    
00500	                           LEAP STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	7-1.    
01300	
01400	<leap_statement>         ::= <set_statement>
01500	                         ::= <associative_statement>
01600	                         ::= <loop_statement> 
01700	
01800	<set_statement>          ::= <set_assignment>
01900	                         ::= PUT <construction_item_expression> IN 
02000	                                <set_variable>
02100	                         ::= REMOVE <retrieval_item_expression> FROM 
02200	                                <set_variable> 
02300	
02400	<associative_statement>  ::= <item_assignment>
02500	                         ::= DELETE ( <retrieval_item_expression> )
02600	                         ::= MAKE <construction_triple>
02700	                         ::= ERASE <retrieval_triple> 
02800	   
02900	   
03000	
03100	<loop_statement>         ::= FOREACH <binding_list> 
03200	                                <associative_context> DO <statement>
03300	                         ::= NEEDNEXT <loop_statement> 
03400	
03500	<binding_list>           ::= <id_list> |
03600	
03700	                         ::= <id_list> SUCH THAT 
03800	
03900	<associative_context>    ::= <element>
04000	                         ::= <associative_context> AND <element>
04100	                         ::= <associative_context> ∧ <element> 
04200	
04300	<element>                ::= <retrieval_associative_expression> IN 
04400	                                <retrieval_set_expression>
04500	                         ::= <retrieval_triple>
04600	                         ::= ( <boolean_expression> ) 
04700	
04800	<λ_triple>               ::= <λ_derived_set> ≡ 
04900	                                <λ_associative_expression> 
05000	   
     

00100	SAILON NO. 57.2					SAIL   7-1
00200	
00300	   
00400	   
00500	SEMANTICS
00600	   
00700	LEAP Introduction
00800	   
00900	   
01000	7-2.    The basic ALGOL facility  in  SAIL  has  been  extended  with
01100	syntactic  constructs  and  semantic  interpretations to reference an
01200	associative data store.  This extension was developed by J.   Feldman
01300	and P.  Rovner and is described in [Feldman].  The LEAP facilities in
01400	SAIL differ slightly from those published in the  CACM  article.   In
01500	the  discussion  of the use of the associative facilities, reasonably
01600	simple examples are given for each  construct.   These  examples  and
01700	associated  discussions  should emphasize the differences between the
01800	SAIL implementation and the constructs published in the CACM article.
01900	   
02000	   
02100	7-3.    The LEAP constructs all involve manipulations  of  one  basic
02200	entity,   the  item.   An  item  is  a  conceptual  entity  which  is
02300	represented at execution time by a unique  number.   Associated  with
02400	each item in the universe is a DATUM.  The DATUM of an item may be an
02500	algebraic quantity, an array of such quantities, or a SET.  The DATUM
02600	assignment  statement  (see  Datum Assignments, 4-7) is used to store
02700	the value of an expression into the DATUM of an item.  The DATUM of a
02800	declared  ARRAY  ITEM is loaded automatically when the block in which
02900	the ARRAY ITEM is declared is entered.  The DATUM of an item may also
03000	be referenced during evaluation of expressions (see Datums, 11-6).
03100	Examples:
03200		INTEGER ITEM father,joe;
03300		INTEGER ARRAY ITEM ages [1:20];
03400		INTEGER a,b,c;
03500	
03600		DATUM (father) ← 21 ;
03700		DATUM (ages) [b] ← b / 33 ;
03800		c ← DATUM (joe) - 12 ;
03900	   
04000	The  DATUM  operator  is  intended  to  link the powerful associative
04100	processing routines developed for  manipulation  of  items  with  the
04200	algebraic  facilities  of  ALGOL.   This link is made as efficient as
04300	possible -- only two machine instructions are required to access  the
04400	DATUM of an item.
     

00100	SAILON NO. 57.2					SAIL   7-4
00200	
00300	   
00400	   
00500	7-4.    Items  or  information about items may be stored in a variety
00600	of ways.  The simple entity ITEM  does  not  itself  occupy  storage.
00700	Instead,  instances  of  ITEMS  are  stored  in  ITEMVARS,  SETS,  or
00800	associations.  The simplest of these forms is the  ITEMVAR:  an  item
00900	may  be "stored" in an ITEMVAR.  Evaluation of that ITEMVAR will then
01000	yield the item stored into it.  ITEMVARS are thus  roughly  analogous
01100	to simple arithmetic variables.  SAIL also allows arrays of ITEMVARs,
01200	with the obvious interpretation.   A  typical  declaration  would  be
01300	"ITEMVAR ARRAY x[1:22,0:1]", or "INTEGER ITEMVAR ARRAY y[1:20]".
01400	   
01500	   
01600	7-5.    Instances   of   items   may  also  be  stored  as  unordered
01700	collections,  or  SETS.   Facilities  are  provided  for  common  set
01800	operations  (see  Set  Expressions,  10-2).  The SAIL system uses one
01900	word of storage for each item in a set.  A set will contain  at  most
02000	one  instance of a specific item: if an instance of item X is already
02100	in set S, then any subsequent attempts to put an instance of X  in  S
02200	will   have  no  effect.   This  is  in  keeping  with  the  standard
02300	mathematical notion of set.
02400	   
02500	   
02600	7-6.    The third, and perhaps most important,  form  of  storage  of
02700	item  instances  is  the  association, or triple.  Ordered triples of
02800	item instances may be written into or retrieved from a special store,
02900	the  associative  store.   The  method of storage of these triples is
03000	designed to  facilitate  fast  and  flexible  retrieval.   SAIL  uses
03100	approximately two words of storage for each triple in the associative
03200	store.  There is at most one copy of a triple in  the  store  at  any
03300	time.   Once  a triple has been stored in the associative memory, its
03400	component item instances may not be changed.  In the  examples  which
03500	follow, a triple is represented by:
03600	   
03700		A ⊗ O ≡ V
03800	   
03900	where  A,  O, and V are items or itemvars.  A, O, and V are mnemonics
04000	for the three components of a triple: attribute, object,  and  value.
04100	The  exact  syntactic  rules  for describing triples are discussed in
04200	SEMANTICS, 10-2.
     

00100	SAILON NO. 57.2					SAIL   7-7
00200	
00300	   
00400	   
00500	General Restrictions
00600	   
00700	   
00800	7-7.    The implementation of the associative store and  other  forms
00900	of  item  storage imposes several limitations on the LEAP capability.
01000	The maximum number of items (as represented by their unique  numbers)
01100	is  4090.   This arises from an overwhelming desire to store a triple
01200	in one word of storage, and hence the requirement that an item number
01300	be describable in 12 bits.
01400	   
01500	   
01600	Construction - Retrieval Distinction
01700	   
01800	   
01900	7-8.    There  are  two  basic  operations which are performed on the
02000	three types of item stores -- construction of a new element  in  that
02100	store, and retrieval of some existing element in the store.  For some
02200	purposes,  it  is  necessary  to  distinguish  the  operations  being
02300	performed.   This  distinction manages to find its way to the syntax.
02400	In the discussion of associative expressions (Item Constructs, 10-4),
02500	the    syntactic    forms    <construction_item_primary>    and
02600	<retrieval_item_primary> are  discussed.   The  ascent  from  primary
02700	level to associative expressions preserves these distinctions.  Thus,
02800	one   speaks   of   a   <construction_item_expression>,   or   of   a
02900	<retrieval_item_expression>.   Often  the  BNF  productions  speak of
03000	<λ_item_expressions>.  This is merely a shorthand to denote that  two
03100	separate   sets   of   productions   exist,  one  in  which  λ  means
03200	"construction", and one in which λ means "retrieval".
03300	   
03400	   
03500	PUT and REMOVE
03600	   
03700	   
03800	7-9.    The verbs PUT and REMOVE are  provided  for  easily  altering
03900	sets.  After initialization, all sets are empty.  They may be altered
04000	either by PUTting  item  instances  into  them  or  by  explicit  set
04100	assignment statements.  The PUT statement is executed as follows: the
04200	construction item expression is evaluated, and must  yield  a  single
04300	item.  An instance of this item is then recorded in the set specified
04400	by the set variable.  REMOVE operates in an analogous fashion.  If an
04500	instance  of  the  item  to  be REMOVEd does not occur in the set, an
04600	error message issues forth.
     

00100	SAILON NO. 57.2					SAIL   7-10
00200	
00300	   
00400	   
00500	DELETE
00600	   
00700	   
00800	7-10.    DELETE releases an item from the universe of current  items.
00900	Some small amount of storage is reclaimed in this process, as well as
01000	the unique number associated with the item DELETEd.  Since  there  is
01100	an  upper  limit  on the number of items, the DELETE statement can be
01200	used to free item numbers for other uses.  The DELETE statement in no
01300	way  alters  the  instances  of the DELETEd item which are present in
01400	sets or associations.  The user should be  sure  that  there  are  no
01500	instances  of  the  DELETEd  item  occurring  in  sets,  itemvars  or
01600	associations.  Attempts to reference a DELETEd item in any  way  will
01700	result in confusion.
01800	   
01900	   
02000	MAKE
02100	   
02200	   
02300	7-11.    Associations may be added to the associative memory with the
02400	MAKE statement.  If the association already exists in the  store,  no
02500	alterations  are  made.   The  argument  to  the  MAKE statement is a
02600	construction triple; that  is,  a  triple  composed  of  construction
02700	associative  expressions.   Every  construct  in these expressions is
02800	interpreted in  a  construction  sense.   The  component  associative
02900	expressions  in  this  triple  are  evaluated  left  to  right.  Some
03000	constructs in these expressions (e.g.  see NEW Items, 10-6 or in  the
03100	case  of  bracketed  triples) require that new unique item numbers be
03200	created.  Examples:
03300	   
03400		MAKE item1 ⊗ item2 ≡ item3
03500		MAKE item1 ⊗ itemvar1 ≡ NEW
03600		MAKE item1⊗[item2⊗itemvar1≡item3]≡itemvar_array[23]
03700	   
03800	   
03900	7-12.     The last example involves the use of  a  BRACKETED  TRIPLE.
04000	The  bracketed triple "[item2 ⊗ itemvar1 ≡ item]" which is used as an
04100	associative expression is inserted in the associative store.   A  new
04200	unique  item  number  is generated, which refers to that association.
04300	Various functions (  ISTRIPLE,  FIRST,  SECOND,  THIRD  --  see  Item
04400	Selectors,  10-5)  may  use  an  instance  of  this new item as their
04500	argument.  Consider the following statements:
04600	
04700		MAKE number ⊗ [part ⊗ hand ≡ finger] ≡ new (5);
04800		FOREACH x,y SUCH THAT number ⊗ x ≡ y AND 
04900		  (ISTRIPLE (x) AND FIRST (x) = part) DO
05000			count ← count + DATUM (y) ;
05100	
     

00100	SAILON NO. 57.2					SAIL   7-12
00200	
00300	   
00400	   
00500	ERASE
00600	   
00700	   
00800	7-13.    The ERASE statement is provided to undo the damage  done  by
00900	the  MAKE  statement.   The  same  general class of arguments must be
01000	provided.  ERASE requires a retrieval triple as  its  argument,  thus
01100	eliminating  such  questionable  constructs as NEW from said triples.
01200	However, the construct ANY may appear in a  triple  specification  to
01300	ERASE.   This  allows  a whole slew of appropriate associations to be
01400	erased in one statement.  (Restriction: ERASE ANY  ⊗  ANY  ≡  ANY  is
01500	considered  bad  form, and is as a direct result, forbidden).  Sample
01600	ERASE statements are:
01700	
01800		ERASE item1 ⊗ item2 ≡ item3
01900		ERASE item1 ⊗ itemvar1 ≡ item2
02000		ERASE itemvar1 ⊗ ANY ≡ item1
02100	RESTRICTION -- MAKE and ERASE will  take  only  item  expressions  as
02200	arguments, and will not take set expressions.
02300	   
02400	   
02500	7-14.    In  order  to give the programmer some idea of what is going
02600	on in the associative store, there is a provision to  interrupt  each
02700	MAKE  and  ERASE  operation,  and enter a breakpoint procedure.  This
02800	allows you to  get  at  the  attribute,  object,  and  value  of  the
02900	association  being  written  or  erased.   ERASE foo ⊗ ANY ≡ ANY will
03000	cause  the  breakpoint  procedure  to  be  activated  once  for  each
03100	association that matches the pattern.
03200	
03300	    A breakpoint procedure has a declaration of the form:
03400	PROCEDURE breakp ( ITEM a,o,v).
03500	The  attribute,  object  and  value  of the interrupted operation are
03600	passed in the formal parameters.  The breakpoints are set with  calls
03700	on   two  routines  in  the  LEAP  runtime  routines  (they  are  not
03800	pre-declared, so the appropriate declarations are given below):
03900	   
04000	
04100		EXTERNAL PROCEDURE BRKERS ( PROCEDURE BP );
04200		EXTERNAL PROCEDURE BRKMAK ( PROCEDURE BP );
04300	
04400		BRKMAK ( breakp );  Comment this sets the breakpoint for MAKE;
04500		BRKERS ( breakp ); Comment this sets the breakpoint for ERASE;
     

00100	SAILON NO. 57.2					SAIL   7-15
00200	
00300	   
00400	   
00500	FOREACH Statement
00600	   
00700	   
00800	7-15.    Flexible searching and retrieval are  the  main  motivations
00900	for  using  the  set  and  associative stores.  The FOREACH statement
01000	provides  this  retrieval  facility.   The   FOREACH   statement   is
01100	essentially  a  looping  statement:  the  <statement> after the DO is
01200	executed for  each  group  of  item  instances  in  the  store  which
01300	satisfies  the  FOREACH  specification.   If there are no such groups
01400	present in the store, the body of the statement  is  never  executed.
01500	The  <binding_list> specifies the itemvars which will contain results
01600	of   the   search.     For    instance,    the    simple    construct
01700	FOREACH x SUCH THAT x IN set1 DO procedure(x)  causes the body of the
01800	statement to be executed once for each item instance in the set set1.
01900	During  execution  of  the  body  of  the  statement,  the  itemvar x
02000	evaluates to  the  item  retrieved  from  the  set  set1.   Consider,
02100	however, the FOREACH Statement
02200	   
02300		FOREACH x SUCH THAT x IN set1 AND x IN set2 DO statement
02400	   
02500	This  specification may appear ambiguous, and indeed it is, unless we
02600	define  the  concept  of  BINDING   the   itemvars   in   a   FOREACH
02700	specification.   In  an associative context, an itemvar which appears
02800	in the <binding_list> is said to be FREE until a search specification
02900	has  determined the first requirement on the value of the itemvar (in
03000	a left-to-right scan of the <associative_context>).  After the  first
03100	requirement, it is said to be BOUND.  Thus the <element> in the above
03200	example which reads "x IN set1" specifies a  search  in  which  x  is
03300	free.   The  fact that x is free implies the searching operation.  In
03400	the second element, "x IN set2", x  is  bound.   Thus  no  search  is
03500	conducted  here.  Instead, the question "Does an instance of the item
03600	I am considering for x appear in the set set2?"  is  evaluated.   The
03700	answer  must  be  TRUE in order that the statement be executed with x
03800	evaluating to that item.  In summary,  then,  the  FOREACH  statement
03900	above  specifies  one  search  (  x  IN  set1  )  and  one additional
04000	requirement ( x IN set2 ).
     

00100	SAILON NO. 57.2					SAIL   7-16
00200	
00300	   
00400	   
00500	7-16.    An  element  of  a  FOREACH  specification  may  also  be  a
00600	parenthesized boolean expression.  It is of course requisite that all
00700	itemvars appearing in the boolean expression must be bound, i.e.   no
00800	searching  of  the  associative store will be accomplished during the
00900	evaluation of the boolean expression.  Example:
01000	   
01100		FOREACH x SUCH THAT x IN set1 AND ( DATUM (x) < 21 ) DO ...
01200	   
01300	Only members of set1 with DATUMs less than 21  will  be  selected  by
01400	this  specification.  In the example above (FOREACH Statement, 7-15),
01500	the second <element> could also have  been  written  in  its  boolean
01600	form: ( x IN set2 ).
01700	   
01800	   
01900	7-17.    The most powerful <element> construct is a retrieval triple.
02000	Such  specifications  make  searches  (for  any  FREE  itemvars)   or
02100	verifications (in the case of completely BOUND elements) in the store
02200	of associations.  For example:
02300	   
02400	1.	FOREACH x SUCH THAT a ⊗ o ≡ x DO PUT x IN people_set;
02500	2.	FOREACH x SUCH THAT a ⊗ o ≡ x AND b ⊗ g ≡ x DO ...
02600	   
02700	The aim of statement 1 is clear -- a search is conducted through  the
02800	associative  store for all associations with attribute "a" and object
02900	"o".  If k such associations are discovered, then  the  body  of  the
03000	statement  is  executed  k  times, with x taking on successive values
03100	each time.  The second example is similar, but places  an  additional
03200	constraint  on  the  values of x which should be returned.  Since the
03300	second element (b ⊗  g  ≡  x)  is  completely  BOUND,  no  search  is
03400	conducted,  but a test is made to verify that the association b ⊗ g ≡
03500	x' is in the store, where x' is some item retrieved during the search
03600	for a ⊗ o ≡ x.
03700	   
03800	   
03900	7-18.    In  general,  an  <associative context> is satisfied by some
04000	assignment of item instances to the itemvars in the <binding list> if
04100	all  of  the  <element>s  are  satisfied  under  that  assignment.  A
04200	<boolean expression>  is  satisfied  if  it  evaluates  to  TRUE.   A
04300	<retrieval  triple> containing no <set expression> is satisfied by an
04400	assignment if the association it specifies  is  in  the  universe  of
04500	associations.  A <retrieval triple> containing a <set expression> (or
04600	ANY) is satisfied if there are, in the universe of associations,  any
04700	of  the  associations  formed by substituting elements of the set (or
04800	arbitrary items) in the position occupied by the <set expression>.
     

00100	SAILON NO. 57.2					SAIL   7-19
00200	
00300	   
00400	   
00500	7-19.    With this concept of SATISFIERS,  we  proceed  to  the  more
00600	general  case  with  more than one itemvar cited in the binding list.
00700	Suppose there are α such itemvars.  Then the <statement> is  executed
00800	once  for  each  permutation  of  the  universe  of items among the α
00900	itemvars which SATISFY the associative context.  During the execution
01000	of  the  <statement>,  the α itemvars will evaluate to the particular
01100	permutation which SATISFIED the associative context.
01200	   
01300	   
01400	7-20.    The above description for  several  itemvars  is  sound  but
01500	slightly  misleading.   The  SAIL  implementation  makes no effort to
01600	avoid duplicating a particular permutation of values which  satisfies
01700	the  associative  context.  Thus the <statement> will be executed one
01800	OR MORE times for every permutation which satisfies  the  associative
01900	context.  (See Restrictions and Caveats, 7-22).
     

00100	SAILON NO. 57.2					SAIL   7-21
00200	
00300	   
00400	   
00500	7-21.      Examples  of FOREACH statements with several free itemvars
00600	specified are:
00700	   
00800	1.	FOREACH x,y,z SUCH THAT father⊗x≡y AND father⊗y≡z DO ...
00900	2.	FOREACH x,z SUCH THAT father⊗ (father ⊗ x) ≡ z DO ...
01000	3.	FOREACH x,y SUCH THAT x IN set AND father ⊗ x ≡ y DO ...
01100	4.	FOREACH x,y SUCH THAT father ⊗ x ≡ y AND x IN set DO ...
01200	   
01300	As it happens, 1 and 2 are equivalent.  The compiler actually reduces
01400	2 to 1 by including a dummy itemvar to be analogous to the use of "y"
01500	in the first example.  Examples 3 and  4  are  precisely  equivalent,
01600	that  is,  the  statement will be executed with x and y evaluating to
01700	all the ordered pairs of items which satisfy the (clearly equivalent)
01800	requirements.   There  is,  however, a considerable difference in the
01900	execution efficiency of  these  two  examples.   Example  3  is  more
02000	efficient  since  the  "set"  is  probably quite small, and since the
02100	search of the associative memory with only one free  itemvar  in  the
02200	search  specification  is  rather fast.  The second example, however,
02300	makes a search through the associative memory for all the (x,y) pairs
02400	and  then  discards  those  pairs for which an instance of x does not
02500	occur in the "set".  Listed below in order of  decreasing  efficiency
02600	are the various basic forms of <element>s that are legal.  The effect
02700	of a statement such as 2 above should be calculated by reducing it to
02800	the  form  of  1.   In  the  list  below,  x, y, and z represent free
02900	itemvars, whereas A, O, and V  represent  either  bound  itemvars  or
03000	fixed items.
03100	
03200		A ⊗ O ≡ V	Verification that the triple 
03300					is in the store.
03400		A ⊗ O ≡ x	Only the value is free.
03500		A IN S		Verification that item A is in set S.
03600		x IN S		All items x in the set S.
03700		x ⊗ y ≡ V	Attribute and object are free.
03800		A ⊗ x ≡ V	Only the object is free.
03900		x ⊗ O ≡ V	Only the attribute is free.
04000		A ⊗ x ≡ y	Object and value are free.
04100		x ⊗ O ≡ y	Attribute and value are free.
04200		x ⊗ y ≡ z	PROHIBITED
04300	
     

00100	SAILON NO. 57.2					SAIL   7-22
00200	
00300	   
00400	   
00500	Restrictions and Caveats
00600	   
00700	   
00800	7-22.    i.  The SAIL implementation differs in fundamental ways from
00900	the implementation described  by  Feldman  and  Rovner  in  the  CACM
01000	article.   Their  FOREACH  statement  builds  a  record  of  all  the
01100	permutations which satisfy the associative context, being careful  to
01200	include only one copy of each such permutation.  Then the <statement>
01300	is executed once for each permutation  that  was  stored  during  the
01400	retrieval  operation.   The  SAIL implementation uses the associative
01500	context as a generator of satisfiers.  Thus one group  of  satisfiers
01600	is  found, <statement> is executed for those satisfiers, then another
01700	found, etc.  until all groups of satisfiers  have  been  found.   The
01800	implications of this method are startling:
01900	   
02000	1.   There  is absolutely no way to guarantee that a particular group
02100	of satisfiers is not repeated.  There are methods  of  coding  around
02200	this  problem.   The  user can stuff itemvar arrays with results of a
02300	FOREACH and avoid duplications.  In many  search  specifications  the
02400	nature  of  the  searches (e.g.  sets, where only one copy of an item
02500	instance can occur in the set) avoids duplicate satisfiers.
02600	2.  Operations within <statement> which change the  associative  data
02700	store may affect the subsequent satisfier groups retrieved.  Note the
02800	difficulty in the following:
02900	
03000		FOREACH x,y |
03100	 link ⊗ x ≡ y DO MAKE link ⊗ x ≡ newlink
03200	   
03300	There is another difficulty with ERASE or REMOVE operations inside  a
03400	FOREACH  statement.   The SAIL implementation saves pointers into the
03500	data  structure  during  the  execution  of  the   <statement>.    If
03600	operations  within  that  statement  cause  these  pointers to become
03700	invalid, wild effects will occur.  Care has been taken,  however,  to
03800	make sure that some simple things work correctly:
03900	
04000		FOREACH x |
04100	 link ⊗ x ≡ node DO ERASE link ⊗ x ≡ NODE ;
04200		FOREACH x |
04300	 x ε set1 ∧ x ε set2 DO REMOVE x FROM set1 ;
04400			..... and many more.
     

00100	SAILON NO. 57.2					SAIL   7-23
00200	
00300	   
00400	   
00500	7-23.      During and after the execution of a FOREACH statement, the
00600	values of the bound  itemvars  are  in  general  well-defined.   They
00700	evaluate to the permutation which last satisfied the FOREACH context.
00800	If a GO TO is executed within the <statement>, the values are correct
00900	in  that  they  correspond  to  the group of satisfiers for which the
01000	<statement> was being executed.  The only case in which the  itemvars
01100	are undefined is when the search specified has been exhausted and the
01200	associative context contains a boolean expression.   The  explanation
01300	of  this  restriction is quite simple -- prior to the evaluation of a
01400	boolean expression, the core locations reserved for the  itemvars  in
01500	the  <binding_list>  are  stuffed with the current satisfiers so that
01600	the evaluation of the boolean expression may reference them.
01700	   
01800	   
01900	7-24.    Expression case  statements,  conditional  expressions,  and
02000	procedure   calls   are  all  valid  within  an  associative  context
02100	specification, provided that all itemvars used  in  these  constructs
02200	are BOUND.
     

00100	SAILON NO. 57.2					SAIL   8-1
00200	
00300	                              SECTION 8
00400	                                    
00500	                     ASSEMBLY LANGUAGE STATEMENTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	8-1.    
01300	
01400	<code_block>             ::= <code_head> <code_tail> 
01500	
01600	<code_head>              ::= <code_begin>
01700	                         ::= <code_begin> <block_name>
01800	                         ::= <code_head> <declaration> ; 
01900	
02000	<code_begin>             ::= START_CODE
02100	                         ::= QUICK_CODE 
02200	
02300	<code_tail>              ::= <instruction> END
02400	                         ::= <instruction> END <block_name>
02500	                         ::= <instruction> ; <code_tail> 
02600	
02700	<instruction>            ::= <addresses>
02800	                         ::= <opcode>
02900	                         ::= <opcode> <addresses> 
03000	
03100	<addresses>              ::= <address>
03200	                         ::= <ac_field> ,
03300	                         ::= <ac_field> , <address> 
03400	
03500	<ac_field>               ::= <constant_expression> 
03600	
03700	<address>                ::= <indexed_address>
03800	                         ::= @ <indexed_address> 
03900	
04000	<indexed_address>        ::= <simple_address>
04100	                         ::= <simple_address> ( <index_field> ) 
04200	
04300	<simple_address>         ::= <identifier>
04400	                         ::= <constant_expression>
04500	                         ::= <literal> 
04600	
04700	<literal>                ::= [ <constant_expression> ] 
04800	
04900	<index_field>            ::= <constant_expression> 
     

00100	SAILON NO. 57.2					SAIL   8-1
00200	
00300	
00400	<opcode>                 ::= <constant_expression>
00500	                         ::= PDP-10_opcode 
00600	   
00700	   
00800	   
00900	SEMANTICS
01000	   
01100	   
01200	8-2.    Within   a  START_CODE  (QUICK_CODE)  block,  statements  are
01300	processed by a small  and  weak,  but  hopefully  adequate,  assembly
01400	language  translator.  Each "instruction" places one instruction word
01500	into the output file.
01600	   
01700	   
01800	Declarations in Code Blocks
01900	   
02000	   
02100	8-3.    A code_block behaves like any other  block  with  respect  to
02200	block  structure.   Therefore,  all  declarations  are valid, and the
02300	names given in these declarations  will  be  available  only  to  the
02400	instructions  in  the  code_block.   There  will, in general, be more
02500	Labels than usual declared in these blocks, since a Label may  appear
02600	in  an  address  field, and since jump instructions referring to such
02700	Labels  are  the  only  means  for  transferring  control  within   a
02800	code_block.   Labels  in  code_blocks may refer to instructions which
02900	will be executed, or to those which are not really instructions,  but
03000	data to be manipulated by these instructions (these latter words must
03100	be bypassed in the code by jump instructions).
03200	   
03300	   
03400	Meaning of Instruction Operands
03500	   
03600	   
03700	8-4.    If the <address> in an instruction is  a  constant  (constant
03800	expression), it is assumed to be an immediate or data operand, and is
03900	not relocated.  If  the  <address>  is  an  identifier,  the  machine
04000	address  (relative to the start of the compilation) is used, and will
04100	be relocated to the proper value by the Loader.  If the <address>  is
04200	an  identifier  which  has  been  declared as a formal parameter to a
04300	procedure, addressing arithmetic will be done automatically to get at
04400	the  VALUE  of  the  paramter.   Hence  if  the <address> is a formal
04500	reference parameter, the instruction will be of the form
04600	OP AC,@ -x('17)
04700	where x depends on exactly where the parameter is in the stack.  If a
04800	literal  is used, the address of the compiled constant will be placed
04900	in the instruction.  Any reference to  Strings  will  result  in  the
05000	address  of the second descriptor word (byte pointer) to be placed in
05100	the instruction.
     

00100	SAILON NO. 57.2					SAIL   8-5
00200	
00300	   
00400	   
00500	8-5.    The indirect, index, and AC fields have the same  syntax  and
00600	perform the same functions as they do in the FAIL or MACRO languages.
00700	   
00800	   
00900	8-6.    The  Opcode may be a constant provided by the user, or one of
01000	the  standard   (non   I/O)   PDP-10   operation   codes,   expressed
01100	symbolically.   If  a constant, it should take the form of a complete
01200	PDP-10 instruction, expressed in octal radix (e.g.  DEFINE  TTYUUO  =
01300	"'510000000000";).   Any  bits  appearing  in  fields  other than the
01400	opcode field (first 9 bits) will be OR'ed with the bits  supplied  by
01500	other fields of instructions in which this opcode appears.
01600	   
01700	   
01800	Distinctions Between START_CODE and QUICK_CODE
01900	   
02000	   
02100	8-7.    Before  your instructions are parsed in a block starting with
02200	START_CODE, instructions are executed to leave all accumulators  from
02300	0  through  '15  available for your use.  In this case, you may use a
02400	JRST to transfer control out of the code_block, as long as you do not
02500	leave a procedure, a block with array declarations, a Foreach loop, a
02600	loop with a For list, or a loop which uses the NEXT construct.  In  a
02700	QUICK_CODE  block,  no  accumulator-saving  instructions  are issued.
02800	Ac's '13 through '15 only are free.  In addition, some recently  used
02900	variables   may  be  given  the  wrong  values  if  used  as  address
03000	identifiers (their current values may be contained  in  Ac's  0-'12);
03100	and  control  should  not  leave  the  code_block  except by "falling
03200	through".
03300	   
03400	   
03500	Warning Concerning Default Radix
03600	   
03700	   
03800	8-8.    All integer constants will  be  expressed  in  decimal  radix
03900	unless the octal representation is explicitly used.
     

00100	SAILON NO. 57.2					SAIL   9-1
00200	
00300	                              SECTION 9
00400	                                    
00500	                        ALGEBRAIC EXPRESSIONS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	9-1.    
01300	
01400	<expression>             ::= <simple_expression>
01500	                         ::= <conditional_expression>
01600	                         ::= <assignment_expression>
01700	                         ::= <case_expression> 
01800	   
01900	   
02000	
02100	<conditional_expression> ::= IF <boolean_expression> THEN <expression> 
02200	                                ELSE <expression> 
02300	
02400	<assignment_expression>  ::= <assignment_statement> 
02500	
02600	<case_expression>        ::= CASE <algebraic_expression> OF ( 
02700	                                <expression_list> ) 
02800	
02900	<expression_list>        ::= <expression>
03000	                         ::= <expression_list> , <expression> 
03100	
03200	<simple_expression>      ::= <algebraic_expression>
03300	                         ::= <string_expression>
03400	                         ::= <set_expression>
03500	                         ::= <associative_expression> 
03600	
03700	<boolean_expression>     ::= <expression> 
03800	
03900	<string_expression>      ::= <algebraic_expression> 
04000	   
04100	   
04200	
04300	<algebraic_expression>   ::= <disjunctive_expression>
04400	                         ::= <algebraic_expression> ∨ 
04500	                                <disjunctive_expression> 
04600	
04700	<disjunctive_expression> ::= <negated_expression>
04800	                         ::= <disjunctive_expression> ∧ 
04900	                                <negated_expression> 
     

00100	SAILON NO. 57.2					SAIL   9-1
00200	
00300	
00400	<negated_expression>     ::= ¬ <relational_expression>
00500	                         ::= <relational_expression> 
00600	
00700	<relational_expression>  ::= <algebraic_relational>
00800	                         ::= <leap_relational> 
00900	
01000	<algebraic_relational>   ::= <bounded_expression>
01100	                         ::= <relational_expression> 
01200	                                <relational_operator> 
01300	                                <bounded_expression> 
01400	
01500	<leap_relational>        ::= <retrieval_item_expression> ε 
01600	                                <retrieval_set_expression>
01700	                         ::= <retrieval_item_expression> 
01800	                                <relational_operator> 
01900	                                <retrieval_item_expression>
02000	                         ::= <retrieval_set_expression> 
02100	                                <relational_operator> 
02200	                                <retrieval_set_expression>
02300	                         ::= <retrieval_triple> 
02400	
02500	<relational_operator>    ::= <
02600	                         ::= >
02700	                         ::= =
02800	                         ::= ≤
02900	                         ::= ≥
03000	                         ::= ≠ 
03100	
03200	<bounded_expression>     ::= <adding_expression>
03300	                         ::= <bounded_expression> MAX 
03400	                                <adding_expression>
03500	                         ::= <bounded_expression> MIN 
03600	                                <adding_expression> 
03700	
03800	<adding_expression>      ::= <term>
03900	                         ::= <adding_expression> <add_operator> <term> 
04000	
04100	<adding_operator>        ::= +
04200	                         ::= -
04300	                         ::= LAND
04400	                         ::= LOR
04500	                         ::= EQV
04600	                         ::= XOR 
04700	
04800	<term>                   ::= <factor>
04900	                         ::= <term> <mult_operator> <factor> 
     

00100	SAILON NO. 57.2					SAIL   9-1
00200	
00300	
00400	<mult_operator>          ::= *
00500	                         ::= /
00600	                         ::= %
00700	                         ::= LSH
00800	                         ::= ROT
00900	                         ::= MOD
01000	                         ::= DIV
01100	                         ::= & 
01200	
01300	<factor>                 ::= <primary>
01400	                         ::= <primary> ↑ <primary> 
01500	
01600	<primary>                ::= <algebraic_variable>
01700	                         ::= - <primary>
01800	                         ::= LNOT <primary>
01900	                         ::= ABS <primary>
02000	                         ::= <algebraic_expression> [ <substring_spec> 
02100	                                ]
02200	                         ::= ∞
02300	                         ::= <constant>
02400	                         ::= <function_designator>
02500	                         ::= ( <algebraic_expression> )
02600	                         ::= LENGTH ( <retrieval_set_expression> )
02700	                         ::= LENGTH ( <string_expression> )
02800	                         ::= CVN ( <item_primary> )
02900	                         ::= LOP ( <string_variable> )
03000	                         ::= LDB ( <arithmetic_expression> )
03100	                         ::= ILDB ( <arithmetic_variable> )
03200	                         ::= ISTRIPLE ( <item_expression> ) 
03300	
03400	<substring_spec>         ::= <algebraic_expression> TO 
03500	                                <algebraic_expression>
03600	                         ::= <algebraic_expression> FOR 
03700	                                <algebraic_expression> 
03800	
03900	<function_designator>    ::= <procedure_identifier>
04000	                         ::= <procedure_identifier> ( 
04100	                                <actual_parameter_list> ) 
04200	
04300	<actual_parameter_list>  ::= <actual_parameter>
04400	                         ::= <actual_parameter_list> , 
04500	                                <actual_parameter> 
04600	
04700	<actual_parameter>       ::= <expression>
04800	                         ::= <array_identifier>
04900	                         ::= <procedure_identifier> 
05000	
05100	<algebraic_variable>     ::= <variable> 
     

00100	SAILON NO. 57.2					SAIL   9-1
00200	
00300	
00400	<string_variable>        ::= <variable> 
00500	   
00600	   
00700	   
00800	SEMANTICS
00900	   
01000	Conditional Expressions
01100	   
01200	   
01300	9-2.    A  conditional  expression returns one of two possible values
01400	depending on the logical truth value of the Boolean expression.   For
01500	the  rules  on evaluation of this truth value see Simple Expressions,
01600	9-9 and following.  If the Boolean expression (BE) is true, the value
01700	of  the  conditional  expression  is  the  value  of  the  expression
01800	following the delimiter THEN.  If BE is false,  the  other  value  is
01900	used.  If both expressions are of an algebraic type, the precise type
02000	of the entire conditional expression is  that  of  the  "THEN  part".
02100	Otherwise,  both expressions must be of precisely the same type (Set,
02200	Item, etc.).  Unlike the nested If statement problem, there can be no
02300	ambiguity for conditional expressions, since there is an ELSE part in
02400	every such expression.
02500	   
02600	   
02700	Example
02800	   
02900	   
03000	9-3.    
03100	
03200	  FOURTHDOWN(YARDSTOGO,YARDLINE,IF YARDLINE < 70 THEN PUNT
03300		ELSE IF YARDLINE < 90 THEN FIELDGOAL
03400		ELSE RUNFORIT)
03500	
     

00100	SAILON NO. 57.2					SAIL   9-4
00200	
00300	   
00400	   
00500	Assignment Expressions
00600	   
00700	   
00800	9-4.    The somewhat weird syntax for an assignment expression (it is
00900	equivalent  to  that  for  an  assignment  statement)  is nonetheless
01000	accurate: the two function identically as far as the new value of the
01100	left part variable is concerned.  The difference is that the value of
01200	this left part variable is also retained as the value of  the  entire
01300	expression.   Assuming that the assignment itself is legal (following
01400	the rules given in Assignment Statements, 4-3 above), the type of the
01500	expression  is that of the left part variable.  This variable may now
01600	participate in any surrounding expressions as if it  had  been  given
01700	its new value in a separate statement on the previous line.  Only the
01800	← operator is valid in assignment expressions.   The  ↔  operator  is
01900	valid only at statement level.
02000	   
02100	   
02200	Example
02300	   
02400	   
02500	9-5.    
02600	
02700	  IF (I←I+1) < 30 THEN I←0 ELSE I←I+1;
02800	
02900	   
03000	   
03100	Case Expressions
03200	   
03300	   
03400	9-6.    The expression
03500	
03600	
03700	    CASE AE OF (E0, E1, E2, ... , En) is equivalent to
03800	
03900	    IF          AE=0 THEN E0 
04000		ELSE IF AE=1 THEN E1
04100		ELSE IF AE=2 THEN E2
04200		...
04300		ELSE IF AE=n THEN En
04400	    ELSE ERROR
04500	
04600	   
04700	   
04800	9-7.    The  type  of  the entire expression is therefore that of E0.
04900	If any of the expressions E1 ...  En cannot be fit into this mold  an
05000	error message is issued by the compiler.
     

00100	SAILON NO. 57.2					SAIL   9-7
00200	
00300	   
00400	   
00500	Example
00600	   
00700	   
00800	9-8.    
00900	
01000	
01100	  OUT(TTY,CASE ERRNO OF("BAD DIRECTORY",
01200			"IMPROPER DATA MODE",
01300			"UNKNOWN I/O ERROR",
01400			...
01500			"COMPUTER IN BAD MOOD"));
01600	
01700	   
01800	   
01900	Simple Expressions
02000	   
02100	   
02200	9-9.    Simple  expressions  are  simple  only  in  that they are not
02300	conditional, case, or assignment expressions.  There are in fact some
02400	exciting   complexities  to  be  discussed  with  respect  to  simple
02500	expressions.  Set, Item, and Associative expressions are discussed in
02600	the  next section.  Before continuing with a description of algebraic
02700	expressions in the following paragraphs, an explanation  of  what  is
02800	meant by a Boolean expression is in order.
02900	   
03000	   
03100	The Boolean Expression Anomaly
03200	   
03300	   
03400	9-10.    You  will  notice that in the syntax a Boolean expression is
03500	said to be equivalent to an expression.  In actuality, the  expression
03600	may  NOT  be  an associative one.  This is simply a way of expressing
03700	syntactically that there are  automatically  invoked  rules,  1)  for
03800	obtaining  a  logical  truth  value from an expression which does not
03900	contain any logical operators or  logical  connectives,  and  2)  for
04000	obtaining  an  algebraic  (Integer)  value  from one which does.  The
04100	rules are very simple:
     

00100	SAILON NO. 57.2					SAIL   9-11
00200	
00300	   
00400	   
00500	Integer, Real, or String to "Boolean"
00600	   
00700	   
00800	9-11.    The logical truth value of an expression  `X'  which  is  of
00900	type  Integer,  Real, or String is the same as the truth value of the
01000	expression `X≠0'.  A  String  expression  will  be  converted  to  an
01100	Integer  one  (see  String-Arithmetic  Conversions,  9-27) before the
01200	comparison is made.  This need not be done for a Real expression,  of
01300	course,  since  the  Integer  and  Real representations for 0 are the
01400	same.  This means you can write expressions of the form
01500	
01600	    IF I+3 THEN E1 ELSE E2      when you really mean
01700	    IF I+3≠0 THEN E1 ELSE E2
01800	
01900	One application of this rule can be found in several of the execution
02000	time  routines  (ENTER, LOOKUP, etc.) where an error flag is returned
02100	which is zero (FALSE) if the operation was  successful  and  non-zero
02200	(TRUE)  if  an  error occurred.  This flag may be tested as a Boolean
02300	variable (IF FLAG THEN  ERROR("LOOKUP  FAILED")  )  or  to  determine
02400	exactly what went wrong by examining its actual value.
02500	   
02600	   
02700	"Boolean" to Integer
02800	   
02900	   
03000	9-12.    The   truth   value  of  an  expression  containing  logical
03100	operators and/or connectives may be determined by rules  given  below
03200	(see  Algebraic  Expressions,  9-15,  Disjunctive  Expressions, 9-18,
03300	Logical Expressions, 9-31).  If this value  is  needed  to  determine
03400	which part to execute in a conditional statement, while statement, or
03500	conditional expression no actual numerical value need be created  for
03600	the  expression  --  the  tests  which determine the truth value lead
03700	directly to the correct program branch.  However, if this  expression
03800	is  combined  with  other  algebraic  expressions  using  some numeric
03900	operator, or if it is assigned to an algebraic variable, some  actual
04000	value  must  be  returned  for  the expression.  If the expression is
04100	false, a zero is returned.   A  non-zero  value  indicates  that  the
04200	expression  is  true.  The actual value returned for true expressions
04300	may differ from time to time, but it is guaranteed non-zero.
     

00100	SAILON NO. 57.2					SAIL   9-13
00200	
00300	   
00400	   
00500	Precedence of Algebraic Operators
00600	   
00700	   
00800	9-13.    The binary  operators  in  SAIL  generally  follow  "normal"
00900	precedence  rules.   That  is,  exponentiations  are performed before
01000	multiplications or divisions, which  in  turn  are  performed  before
01100	additions  and subtractions, etc.  The bounding operators MAX and MIN
01200	are performed after these operations.  The logical connectives ∧  and
01300	∨,  when  they  occur,  are  performed last ( ∧ before ∨).  The exact
01400	precedence of operators is described in the syntax above.  The  order
01500	of  operation  can be changed by including parentheses at appropriate
01600	points (see Primaries, 9-40).
     

00100	SAILON NO. 57.2					SAIL   9-14
00200	
00300	   
00400	   
00500	9-14.    In  an  expression  where  several  operators  of  the  same
00600	precedence occur at the same level, the operations are performed from
00700	left  to  right.   See  Algebraic  Expressions,   9-15,   Disjunctive
00800	Expressions,   9-18   for   special   evaluation  rules  for  logical
00900	connectives.
01000	   
01100	Expression Evaluation Rules
01200	   
01300	   
01400	9-14.    SAIL  does  not   evaluate   expressions   in   a   strictly
01500	left-to-right  fashion.  If we are not constrained to a left-to-right
01600	evaluation,  (as  is  ALGOL  60),  we  can  in  some  cases   produce
01700	considerably  better  code  than  a strict left-to-right scheme could
01800	achieve.  Intuitively, The essential features (and pitfalls) of  this
01900	evaluation rule can be illustrated by a simple example:
02000	
02100		REAL PROCEDURE halve ( REFERENCE REAL whole );
02200			RETURN ( whole←whole/2 );
02300	
02400		b ← 2.6 ;
02500		c ← b + halve (b) ;
02600	
02700	The  last  assignment  statement  is evaluated as follows: first call
02800	halve, with a reference to b as its argument; upon return, add  b  to
02900	the procedure call result; then store the result (which is 2.6) in c.
03000	If we were doing a strict left-to-right evaluation, the  value  of  b
03100	would  have  to  be saved before the procedure halve was called.  The
03200	evaluation scheme can be stated quite simply: no  code  is  generated
03300	for the operation represented by a BNF production until the reduction
03400	of that BNF production takes place.  The evaluation rules can also be
03500	stated  a  little  more  elegantly, by defining a function EVAL whose
03600	value is a REFERENCE to some computed value.  EVAL  (variable)  is  a
03700	reference  to  that  variable.   EVAL  ( thing1 operation thing2 ) is
03800	DO-OPERATION (operation, EVAL(thing1),EVAL(thing2))),    where
03900	DO-OPERATION  returns  a  reference  to  the  resulting  value.  Here
04000	thing1, operation, and thing2 are abstract entities, merely  intended
04100	to suggest the various concrete syntactic constructs.
04200	   
04300	   
04400	Algebraic Expressions
04500	   
04600	   
04700	9-15.    If  an  algebraic expression has as its major connective the
04800	logical connective "∨", the expression has  the  logical  value  TRUE
04900	(arithmetic  value  some non-zero integer) if either of its conjuncts
05000	(the expressions surrounding the "∨") is true; FALSE otherwise.
     

00100	SAILON NO. 57.2					SAIL   9-16
00200	
00300	   
00400	   
00500	9-16.     A∨B does NOT produce the bit-wise Or of A and B if they are
00600	algebraic  expressions.   Truth  values combined by numeric operators
00700	will in general be meaningless (use the operators LOR  and  LAND  for
00800	bit operations).
00900	   
01000	   
01100	9-17.    The  user  should be warned that in an expression containing
01200	logical connectives, only enough of the expression is evaluated (from
01300	left  to  right)  to uniquely determine its truth value.  Thus in the
01400	expression
01500	
01600	    (J<3 ∨ (K←K+1) > 0),
01700	
01800	K will not be incremented if J  is  less  than  3  since  the  entire
01900	expression is already known to be true.  Conversely in the expression
02000	
02100	    (X ≥0 ∧ SQRT(X)>2) (see Disjunctive Expressions, 9-18),
02200	
02300	there is never any danger of attempting to extract the square root of
02400	a negative X, since the failure of the first test  testifies  to  the
02500	falsity  of  the  entire  expression  -- the SQRT routine is not even
02600	called in this case.
02700	   
02800	   
02900	Disjunctive Expressions
03000	   
03100	   
03200	9-18.    If a disjunctive expression has as its major connective  the
03300	logical  connective "∧", the expression has the logical value TRUE if
03400	both of its disjuncts are TRUE; FALSE otherwise.  Again, if the first
03500	disjunct is FALSE a logical value of FALSE is obtained for the entire
03600	expression without further evaluation.
03700	   
03800	   
03900	Relational Expressions
04000	   
04100	   
04200	9-19.    If any of the binary relational  operators  is  encountered,
04300	code  is produced to convert any String arguments to Integer numbers.
04400	Then type  conversion  is  done  as  it  is  for  +  operations  (see
04500	Arithmetic  Type  Conversions,  9-21).   The values thus obtained are
04600	compared for the indicated condition.  A Boolean value TRUE or  FALSE
04700	is  returned  as  the  value  of  the expression.  Of course, if this
04800	expression is used in subsequent arithmetic operations, a  conversion
04900	to  integer  (see  "Boolean"  to Integer, 9-12 above) is performed to
05000	obtain an Integer value.
     

00100	SAILON NO. 57.2					SAIL   9-20
00200	
00300	   
00400	   
00500	9-20.    Leap relational operators are discussed in depth in a  later
00600	section.
00700	   
00800	   
00900	Arithmetic Type Conversions
01000	   
01100	   
01200	9-21.    The  binary arithmetic, logical, and String operations which
01300	follow will accept combinations of arguments of any algebraic  types.
01400	The type of the result of such an operation is sometimes dependent on
01500	the type of its arguments and sometimes fixed.  An  argument  may  be
01600	converted  to  a  different  algebraic  type  before the operation is
01700	performed.   The  following  table  describes  the  results  of   the
01800	arithmetic  and logical operations given various combinations of Real
01900	and Integer inputs.  ARG1 and ARG2 represent the types of the  actual
02000	arguments.   ARG1'  and  ARG2'  represent  the types of the arguments
02100	after any necessary conversions have been made.
     

00100	SAILON NO. 57.2					SAIL   9-22
00200	
00300	   
00400	   
00500	9-22.    
00600	   
00700	OPERATION     ARG1   ARG2   ARG1'  ARG2'  RESULT
00800	   
00900	+ -           INT    INT    INT    INT    INT*
01000	* ↑ %         REAL   INT    REAL   REAL   REAL
01100	MAX MIN       INT    REAL   REAL   REAL   REAL
01200	              REAL   REAL   REAL   REAL   REAL
01300	   
01400	LAND LOR      INT    INT    INT    INT    INT
01500	EQV XOR       REAL   INT    REAL   INT    REAL
01600	              INT    REAL   INT    REAL   INT
01700	              REAL   REAL   REAL   REAL   REAL
01800	   
01900	LSH ROT       INT    INT    INT    INT    INT
02000	              REAL   INT    REAL   INT    REAL
02100	              INT    REAL   INT    INT    INT
02200	              REAL   REAL   REAL   INT    REAL
02300	   
02400	/             INT    INT    REAL   REAL   REAL
02500	              REAL   INT    REAL   REAL   REAL
02600	              INT    REAL   REAL   REAL   REAL
02700	              REAL   REAL   REAL   REAL   REAL
02800	   
02900	MOD DIV       INT    INT    INT    INT    INT
03000	              REAL   INT    INT    INT    INT
03100	              INT    REAL   INT    INT    INT
03200	              REAL   REAL   INT    INT    INT
03300	   
03400	* Unless ARG2 is <0 for the operator ↑
03500	   
03600	   
03700	9-23.    An Integer is converted to a Real number in such a way  that
03800	if this Real number is converted back to an Integer, the same Integer
03900	value will result, unless the absolute value of the number is greater
04000	than  134217728.   Some  low-order  significance  will  be  lost  for
04100	integers greater than this magnitude.
04200	   
04300	   
04400	9-24.    If the Integer is a SHORT INTEGER variable, or the  Real  is
04500	SHORT  REAL, the conversion is done with a FSC instruction, much more
04600	efficiently (a factor of about 8) than the normal UUO.
     

00100	SAILON NO. 57.2					SAIL   9-25
00200	
00300	   
00400	   
00500	9-25.    A Real number is converted to an Integer using the following
00600	formula:
00700	
00800	   Integer ← SIGN(Real)*{largest integer I such that I≤ABS(Real)}.
00900	
01000	This  function  will  produce invalid results for Real numbers with a
01100	magnitude greater than 134217728.   If  either  operand  is  declared
01200	SHORT,  conversion  is  done  (Stanford  only)  with the built-in FIX
01300	instruction, at a correspondingly faster  rate.   As  usual,  caution
01400	must be taken that the range of the number is that of a SHORT Integer
01500	(27 bits).
01600	   
01700	   
01800	9-26.    If a String is presented as an  argument  to  any  of  these
01900	operations,  it  is  converted  to an Integer.  If an Integer or Real
02000	argument is presented  to  the  concatenation  operator  (&),  it  is
02100	converted to a one-character string.  Here are the rules:
02200	   
02300	   
02400	String-Arithmetic Conversions
02500	   
02600	   
02700	9-27.    If  a  String  is  presented as an argument to an arithmetic
02800	operator, as a (value) parameter to a procedure which expects a  Real
02900	or  Integer  value, or as an expression to be stored by an assignment
03000	statement into a Real  or  Integer  variable,  an  Integer  value  is
03100	created for it as follows:
03200	
03300	    If  the  string is the null string (length=0), a 0 is returned as
03400	its `Integer value'.  Otherwise a word which has its lefthand 29 bits
03500	0, the rightmost 7 bits containing the first character of the String,
03600	is returned as its `Integer value'.  For instance, the String "ABCDE"
03700	has  as  its  `Integer  value'  '101, the octal representation of the
03800	letter `A'.  This Integer will then be converted to a Real number, if
03900	necessary.
     

00100	SAILON NO. 57.2					SAIL   9-28
00200	
00300	   
00400	   
00500	9-28.    If  an Integer or Real number is presented where a String is
00600	expected, a one character String  will  be  created  whose  character
00700	consists  of  bits  29-35  (the  rightmost seven bits) of the numeric
00800	value.  A Real number is not  converted  to  an  Integer  before  the
00900	conversion.  For instance, the expression
01000	   
01100	    "STRING"& '15 & '12
01200	   
01300	will  result  in  a  String which is 8 characters long.  The last two
01400	characters are the ASCII codes for carriage  return  and  line  feed,
01500	respectively.
01600	   
01700	   
01800	Bounded Expressions
01900	   
02000	   
02100	9-29.    A  MAX  B  (where A and B are appropriate expressions -- see
02200	the Syntax) has the value of the larger of A and B (in the  algebraic
02300	sense).   Type conversions are performed as if the operator were `+'.
02400	0 MAX X MIN 10 is X if 0≤X≤10, 0 if X<0, 10 if X>10.
02500	   
02600	   
02700	Adding Expressions
02800	   
02900	   
03000	9-30.    All  the   operators   grouped   in   the   semantic   class
03100	<add_operator>  operate  at the same precedence level.  The user must
03200	sometimes provide parentheses in order to make the  meaning  of  such
03300	expressions  absolutely  unambiguous.   The + and - operators will do
03400	integer addition (subtraction) if both  arguments  are  integers  (or
03500	converted to integers from strings); otherwise, rounded Real addition
03600	or subtraction, after necessary conversions, is done.
03700	   
03800	   
03900	9-31.    LAND,  LOR,  XOR,  and  EQV  carry  out  bit-wise  And,  Or,
04000	Exclusive Or, and Equivalence operations on their arguments.  No type
04100	conversions are done for these functions.  The logical connectives  ∧
04200	and ∨ do not have this effect -- they simply cause tests and jumps to
04300	be compiled.  The type of the result is that of  the  first  operand.
04400	This  allows  expressions  of  the form X LAND '777777777, where X is
04500	Real, if they are really desired.
04600	   
04700	   
04800	9-32.    Currently the values of the various overflow flags  produced
04900	by  these operators (and those which follow) are not available to the
05000	user.
     

00100	SAILON NO. 57.2					SAIL   9-32
00200	
00300	   
00400	   
00500	Terms
00600	   
00700	Arithmetic Multiplicative Operators
00800	   
00900	   
01000	9-33.    The operation * (multiplication), like + and  -,  represents
01100	Integer  multiplication  only  if  both  arguments are integers; Real
01200	otherwise.  Integer multiplication uses the IMUL machine  instruction
01300	-- no double-length result is available.
01400	   
01500	   
01600	9-34.    The / operator (division) always does rounded Real division,
01700	after converting any Integer arguments to Real.
01800	   
01900	   
02000	9-35.    The % operator has the same type table as +, -, and  *.   It
02100	performs whatever division is appropriate.
02200	   
02300	   
02400	9-36.    LSH  and ROT provide logical shift operations on their first
02500	arguments.  If the value of the second argument is positive, a  shift
02600	or  rotation  of  that  many bits to the left is performed.  If it is
02700	negative, a right-shift or rotate is done.  To obtain  an  arithmetic
02800	shift (ASH) operation, multiply or divide by the appropriate power of
02900	2; the compiler will change this operation to a shift operation.
03000	   
03100	   
03200	9-37.    DIV and MOD force  both  arguments  to  be  integers  before
03300	dividing.   X MOD Y  is  the  remainder  after  X  DIV Y is performed
03400	(X MOD Y = X - (X DIV Y)*Y);
03500	   
03600	   
03700	Concatenation Operator
03800	   
03900	   
04000	9-38.    This operator produces a result of type String.  It  is  the
04100	String  with  length  the  sum  of  the  lengths  of  its  arguments,
04200	containing all the characters of the second  string  concatenated  to
04300	the  end of all the characters of the first.  The operands will first
04400	be   converted   to   strings   if   necessary   as   described    in
04500	String-Arithmetic  Conversions,  9-27 above.  The normal use of the &
04600	operator is to collect lines  of  text,  from  several  other  string
04700	sources,  which  will  subsequently  be  sent  to  an  output device.
04800	Numbers can be converted to strings representing their external forms
04900	(and  vice-versa)  through  explicit calls on execution time routines
05000	like CVS and CVD (see Execution Routines, 12-1 below).
     

00100	SAILON NO. 57.2					SAIL   9-38
00200	
00300	   
00400	   
00500	Factors
00600	   
00700	   
00800	9-39.    A factor is either a primary or a primary raised to a  power
00900	represented by another primary.  As usual, evaluation is from left to
01000	right, so that A↑B↑C is evaluated as (A↑B)↑C.  In the factor  X↑Y,  a
01100	suitable  number  of  multiplications  and  additions is performed to
01200	produce an "exact" answer if Y is a positive  integer.   Otherwise  a
01300	routine  is  called  to approximate ANTILOG(Y LOG X).  The result has
01400	the type of X in the former case.  It is always of type Real  in  the
01500	latter.
01600	   
01700	   
01800	Primaries
01900	   
02000	   
02100	9-40.    A  primary  represents  an  arithmetic or String value which
02200	always acts as a unit in any  binary  operation.   It  is  either  an
02300	expression   surrounded  by  parentheses  which  indicates  that  all
02400	internal operations should be  performed  before  combining  it  with
02500	other  things,  or  one  of  myriad  other  constructs  which will be
02600	considered separately.
02700	   
02800	   
02900	Variables and Constants
03000	   
03100	   
03200	9-41.    These  are  clearly  primary  objects.   They   are   values
03300	contained  in  specific core locations, or in parameter stacks, or in
03400	the case of some numeric constants, they are immediate operands.
03500	   
03600	   
03700	Substrings
03800	   
03900	   
04000	9-42.    A  String  primary  which  is  qualified  by   a   substring
04100	specification represents a part of the specified string.  ST[X FOR Y]
04200	represents the Xth through the (X + Y - 1)th characters of the String
04300	ST.  ST[X TO Y] represents the Xth through Yth characters of ST.
     

00100	SAILON NO. 57.2					SAIL   9-43
00200	
00300	   
00400	   
00500	9-43.    Consider the ST[X TO Y] case.  If Y>LENGTH(ST), Y←LENGTH(ST).
00600	if  Y<0,  Y←0;  in either case  the  right half of the global Integer
00700	_SKIP_  is  set  to  TRUE.   If  X  ≤  1 it is set to 1.  If X > (the
00800	modified) Y, it is set to Y+1 (null string  guaranteed).   In  either
00900	case the left half of _SKIP_ is made TRUE.  The ST[X FOR Y] operation
01000	is converted to the ST[X TO Y] case before the substring operation is
01100	performed.
01200	   
01300	   
01400	9-44.    To  examine  the  above conditions, declare EXTERNAL INTEGER
01500	_SKIP_, and look at it after any interesting substring operation.
01600	   
01700	   
01800	Special Length Operator (∞)
01900	   
02000	   
02100	9-45.    This  special  primary  construct  is  valid   only   within
02200	substring brackets.  It is an algebraic value representing the length
02300	of the most immediate string under consideration.
02400	   
02500	   
02600	Example:
02700	   
02800	   
02900	9-46.    
03000	
03100		A[4 to ∞] throws out the first 3 characters of A.
03200		A[3 for B[∞-1 for 1]] uses the next to the last character
03300				      of string B as the number of characters
03400				      for the A substring operation.
03500	   
03600	   
03700	Function Designators
03800	   
03900	   
04000	9-47.    A function designator defines a single value.  This value is
04100	produced  by  the  execution  of a typed user Procedure or of a typed
04200	execution-time routine (Execution Routines, 12-1).   For  a  function
04300	designator to be an algebraic primary, its Procedure must be declared
04400	to have an algebraic type.  Untyped Procedures  may  only  be  called
04500	from Procedure statements (see Procedure Statements, 6-2).  The value
04600	obtained from a user-defined Procedure is that provided by  a  Return
04700	Statement within that Procedure.  If the Procedure does not execute a
04800	Return Statement, the value might  be  anything  at  all.   A  Return
04900	Statement  in  a  typed  Procedure  must  mention a value (see Return
05000	Statement, 5-20).
     

00100	SAILON NO. 57.2					SAIL   9-48
00200	
00300	   
00400	   
00500	9-48.    The rules for supplying  actual  parameters  in  a  function
00600	designator  are  identical  to  those  for  supplying parameters in a
00700	procedure statement (see Procedure Statements, 6-2).
00800	   
00900	   
01000	9-49.    Several of the constructs given here as primaries  have  the
01100	form  of  function designators.  However, the operations necessary to
01200	obtain the values of these constructs are generally compiled directly
01300	into the program.  Descriptions of these functions follow:
01400	   
01500	   
01600	Length
01700	   
01800	   
01900	9-50.    LENGTH   is  always  an  integer-valued  function.   If  its
02000	argument is a set expression, the result is the number  of  Items  in
02100	the  set.   If  the argument is a String, its length is the number of
02200	characters in the string.  The length of an algebraic  expression  is
02300	always 1 (see String-Arithmetic Conversions, 9-27).
02400	   
02500	   
02600	Lop
02700	   
02800	   
02900	9-51.    The  LOP  operator  applied to a String variable removes the
03000	first character from the String and returns it in the form  given  in
03100	String-Arithmetic  Conversions,  9-27  above.   The  String no longer
03200	contains this character.  LOP applied to a null  String  has  a  zero
03300	value.   If  the  argument is a Set expression the result is an Item.
03400	This case is described below (Item Constructs, 10-4).
03500	   
03600	   
03700	Cvn
03800	   
03900	   
04000	9-52.    CVN has as its value  the  Integer  which  is  the  internal
04100	representation  of  its  Item  argument.   This  function  is  highly
04200	implementation-dependent, and should only be used by people  who  are
04300	willing  to  follow  the  compiler writers around a lot.  Its inverse
04400	function is CVI, described in Item Constructs, 10-4 below.
     

00100	SAILON NO. 57.2					SAIL   9-53
00200	
00300	   
00400	   
00500	Lnot
00600	   
00700	   
00800	9-53.    The unary operator Lnot produces the bitwise  complement  of
00900	its  (algebraic)  argument.   No  type conversions (except strings to
01000	integers) are performed on the argument.   The  type  of  the  result
01100	(meaningful or not) is the type of the argument.
01200	   
01300	   
01400	Abs
01500	   
01600	   
01700	9-54.    The   unary   operator  ABS  is  valid  only  for  algebraic
01800	quantities.  It returns the absolute value of its argument.
01900	   
02000	   
02100	Unary Minus
02200	   
02300	   
02400	9-55.    -X  is  equivalent  to  (0-X).   No  type  conversions   are
02500	performed.
02600	   
02700	   
02800	Boolean Primaries
02900	   
03000	   
03100	9-56.    The  unary  Boolean  operator  ¬ applied to an argument BE(a
03200	relational expression, see Syntax) has the value TRUE if BE is false,
03300	and  FALSE  if  BE  is  true.   Notice  that  ¬A  is  not the bitwise
03400	complement of A, if A is an algebraic value.  If used as an algebraic
03500	value,  ¬A  is simply 0 if A≠0 (see "Boolean" to Integer, 9-12), some
03600	non-zero Integer otherwise.
     

00100	SAILON NO. 57.2					SAIL   9-57
00200	
00300	   
00400	   
00500	ISTRIPLE
00600	   
00700	   
00800	9-57.    
00900	   
01000	   
01100	9-57.    Istriple (IE) is TRUE if IE is an  Item  which  describes  a
01200	bracketed  triple.   It  is  FALSE  otherwise.   If IE is not an Item
01300	expression, the compiler will complain bitterly.
01400	
01500	   ISTRIPLE ( [A⊗B≡V] ) is true.
01600	
01700	   ISTRIPLE ( <declared item> ) is false.
01800	
01900	   
02000	   
02100	LDB and ILDB
02200	   
02300	   
02400	9-58.    LDB and ILDB are SAIL constructs used to invoke  the  PDP-10
02500	byte  loading  instructions.   The  arguments  to these functions are
02600	expressions which are interpreted as byte pointers.  In the  case  of
02700	ILDB,  you  are required to use an algebraic variable as argument, so
02800	that  the  byte  pointer  (i.e.   that  algebraic  variable)  may  be
02900	incremented.
     

00100	SAILON NO. 57.2					SAIL   10-1
00200	
00300	                              SECTION 10
00400	                                    
00500	                   SET AND ASSOCIATIVE EXPRESSIONS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	10-1.    
01300	
01400	<set_expression>         ::= <λ_set_expression> 
01500	
01600	<λ_set_expression>       ::= <λ_set_term>
01700	                         ::= <λ_set_expression> ∪ <λ_set_term> 
01800	
01900	<λ_set_term>             ::= <λ_set_factor>
02000	                         ::= <λ_set_term> ∩ <λ_set_factor> 
02100	
02200	<λ_set_factor>           ::= <λ_set_primary>
02300	                         ::= <λ_set_factor> - <λ_set_primary> 
02400	
02500	<λ_set_primary>          ::= PHI
02600	                         ::= <set_variable>
02700	                         ::= {λ_item_expr_list}
02800	                         ::= ( <λ_set_expression> )
02900	                         ::= <λ_derived_set> 
03000	
03100	<λ_item_expr_list>       ::= <λ_item_expression>
03200	                         ::= <λ_item_expr_list> , <λ_item_expression> 
03300	
03400	<λ_derived_set>          ::= <λ_associative_expr> 
03500	                                <associative_operator> 
03600	                                <λ_associative_expr> 
03700	
03800	<associative_operator>   ::= ⊗
03900	                         ::= `
04000	                         ::= * 
04100	   
04200	   
04300	
04400	<associative_expression> ::= <λ_associative_expr> 
04500	
04600	<λ_associative_expr>     ::= <λ_item_expression>
04700	                         ::= <λ_set_expression> 
     

00100	SAILON NO. 57.2					SAIL   10-1
00200	
00300	
00400	<λ_item_expression>      ::= <λ_item_primary>
00500	                         ::= <selector> ( <λ_item_primary> )
00600	                         ::= [ <λ_item_primary> ⊗ <λ_item_primary> ≡ 
00700	                                <λ_item_primary> ] 
00800	
00900	<construction_item_prim> ::= <item_primary>
01000	                         ::= NEW
01100	                         ::= NEW ( <algebraic_expression> )
01200	                         ::= NEW ( <array_name> ) 
01300	
01400	<retrieval_item_prim>    ::= <item_primary>
01500	                         ::= ANY 
01600	
01700	<item_primary>           ::= <item_identifier>
01800	                         ::= <itemvar_variable>
01900	                         ::= CVI ( <algebraic_expression> )
02000	                         ::= COP ( <set_variable> )
02100	                         ::= LOP ( <set_variable> ) 
02200	
02300	<λ_triple>               ::= <λ_derived_set> ≡ 
02400	                                <λ_associative_expression> 
02500	
02600	<selector>               ::= FIRST
02700	                         ::= SECOND
02800	                         ::= THIRD 
02900	
03000	<itemvar_variable>       ::= <variable> 
03100	
03200	<set_variable>           ::= <variable> 
03300	
03400	<leap_relational>        ::= <retrieval_associative_expression> IN 
03500	                                <retrieval_set_expression>
03600	                         ::= <retrieval_associative_expression> 
03700	                                <relational_operator> 
03800	                                <retrieval_associative_expression>
03900	                         ::= <retrieval_triple> 
04000	   
     

00100	SAILON NO. 57.2					SAIL   10-2
00200	
00300	   
00400	   
00500	SEMANTICS
00600	   
00700	Set Expressions
00800	   
00900	   
01000	10-2.      Three  rather  standard  operators are implemented for use
01100	with sets.  These are union (∪), intersection  (∩),  and  subtraction
01200	(-).  These operators have the standard mathematical interpretations.
01300	The only possible confusion pertains to subtraction:  if  we  perform
01400	the set operation set1 - set2, and if there is an instance of an item
01500	x in set2 but not in set1, the  subtraction  proceeds  and  no  error
01600	message is given.
01700	   
01800	   
01900	Set Primaries
02000	   
02100	   
02200	10-3.    In  addition  to  the  <set_variable>,  there  are three set
02300	primaries: the empty set PHI, a  set  composed  of  a  list  of  item
02400	expressions,  and  derived  sets.   The  empty  set is the set with a
02500	LENGTH of 0.  Its use is unrestricted.  A set primary  which  results
02600	from  a  list  of  item  expressions  is  put  together  as each item
02700	expression is evaluated.  Derived sets are really sets of answers  to
02800	questions which search the associative memory.  The conventions are:
02900	   
03000		a ⊗ b		-- all x such that a ⊗ b ≡ x
03100		a ` b		-- all x such that a ⊗ x ≡ b
03200		a * b		-- (a ⊗ b) ∪ (a ` b)
03300	   
03400	Examples of set primaries:
03500	   
03600		PHI
03700		{ item1 , item2 , itemprocedure1 }
03800		(item1 ⊗ itemvar1)
03900	
     

00100	SAILON NO. 57.2					SAIL   10-4
00200	
00300	   
00400	   
00500	Item Constructs
00600	   
00700	   
00800	10-4.      There  are  several  SAIL functions which yield items when
00900	evaluated.  This is actually  a  rather  ambiguous  statement,  since
01000	items  as  such  have no real existence as entities to pass around in
01100	the breeze.  But, of course, their unique identifier numbers  may  be
01200	passed  about  freely  and indeed are, since the identifier number is
01300	sufficient to specify an item.   As  explained  earlier,  an  itemvar
01400	evaluates  to  the item last "stored" in that itemvar.  There are two
01500	functions provided for removing item instances from sets.  The  first
01600	of  these  is  COP, which evaluates the <set_expression> argument and
01700	returns an instance of the first item in the set.  The  "first"  item
01800	in  a  set  is  not  well defined, since the sets are unordered.  The
01900	value of the <set_expression> is  unchanged.   The  function  LOP  is
02000	similar  to COP in that its value is an instance of the first item in
02100	the set argument, but the item returned will be removed from the  set
02200	if LOP is used.  The set argument to LOP must be a <variable> for the
02300	simple reason that the set descriptor must be changed to reflect  the
02400	removed item.
02500	   
02600	   
02700	Item Selectors
02800	   
02900	   
03000	10-5.    The  operators  FIRST,  SECOND,  and  THIRD are provided for
03100	decomposing bracketed triples  (see  Bracketed  Triples,  7-12.   The
03200	<item_primary> argument is assumed to be an instance of an item which
03300	was created for the bracketed association when the MAKE was executed.
03400	Examples:
03500		FIRST ( [a⊗o≡v] ) evaluates to a.
03600		SECOND ( [a⊗o≡v] ) evaluates to o.
03700		THIRD ( [a⊗o≡v] ) evaluates to v.
     

00100	SAILON NO. 57.2					SAIL   10-6
00200	
00300	   
00400	   
00500	NEW Items
00600	   
00700	   
00800	10-6.    The  function  NEW  calls  upon  the  associative  store  to
00900	refurbish  a  dusty old DELETEd item or to generate a new one.  These
01000	new items become a part of the universe of existing items, and may be
01100	accessed and handled in precisely the same fashion as declared items.
01200	If NEW is used  in  an  item  expression,  that  expression  is  then
01300	constrained  to be a construction item expression.  NEW may also take
01400	an argument.  In  this  case,  the  datum  of  the  created  item  is
01500	preloaded  with  the  value  passed as argument.  If this argument is
01600	algebraic (real or integer), then the datum will be of the same type.
01700	No  type  conversions  are  done when passing the algebraic argument.
01800	NEW will also accept an array name as argument.  In  this  case,  the
01900	created  item will be of the type array.  In fact, the array cited as
02000	argument will be copied into the newly created array.  The new  array
02100	will have the same bounds and number of dimensions as the array cited
02200	as argument.  This array will not disappear even if the  outer  block
02300	is exited.
02400	   
02500	NEW_ITEM Declaration
02600	   
02700	   
02800	10-6.    The  SAIL  runtime routines allocate several tables based on
02900	the number of items in the world.  The maximum size of  these  tables
03000	is  4096.  In order to conserve storage, the size of these tables may
03100	be specified by the user.  The compiler accounts for all the declared
03200	items  --  it  remains the user's responsibility to estimate how many
03300	generated (NEW) items he will require.  This  specification  is  made
03400	with the REQUIRE verb:
03500	
03600		REQUIRE 2000 NEW_ITEMS;
03700	   
03800	   
03900	ANY Construct
04000	   
04100	   
04200	10-7.    Some    associative   searches   may   need   only   partial
04300	specification -- particular portions of a foreach  specification  may
04400	be  unimportant.   The ANY construct is used to specify exactly which
04500	parts of the specification are "don't care"'s.  Examples are:
04600	   
04700		FOREACH x SUCH THAT father ⊗ x ≡ ANY DO PUT x IN sons;
04800		fathers ← (father ⊗ ANY ) ;
04900	ANY is NOT an item.  It is merely a syntactic arrangement to  specify
05000	the "don't care" condition.  Thus foo ← ANY is illegal
     

00100	SAILON NO. 57.2					SAIL   10-7
00200	
00300	   
00400	   
00500	CVI
00600	   
00700	   
00800	10-8.    The  function CVI is provided for those people who insist on
00900	having the world at their disposal.  The argument is an  integer  and
01000	the  result is an instance of the item which uses that integer as its
01100	unique identifier.  Absolutely no error checking is done.  CVI is for
01200	daring men.
01300	   
01400	   
01500	LEAP Booleans
01600	   
01700	   
01800	10-9.    Several boolean primaries are implemented for comparing sets
01900	and items.  In the following discussion, "ix" means item  expression,
02000	and "se" means set expression.  These are:
02100	1.   Set  Membership.   The  boolean  "ix  IN  se"  evaluates the set
02200	expression, and returns TRUE if the item value specified by the  item
02300	expression is a member of the set.
02400	2.  Association Existence.  The boolean " ix ⊗ ix ≡ ix " returns TRUE
02500	if the association exists in the associative store.  Examples:
02600	   
02700		IF father ⊗ x ≡ joe THEN ...
02800		IF father ⊗ joe ≡ ANY THEN MAKE type ⊗ joe ≡ legitimate
02900	   
03000	3.  Relations.  The  use  of  the  third  kind  of  boolean  is  more
03100	restricted than the syntax implies.  Only the following relations are
03200	valid:
03300	
03400		ix = ix		-- obvious interpretation
03500		ix ≠ ix		-- obvious interpretation
03600		se1 < se2	-- true if se1 is a proper subset of se2
03700		se1 ≤ se2	-- true if se1 is identical to se2 or
03800				    if se1 is a proper subset of se2
03900		se1 = se2	-- obvious interpretation
04000		se1 ≠ se2	-- obvious interpretation
04100		se1 > se2	-- equivalent to se2 < se1
04200		se1 ≥ se2	-- equivalent to se2 ≤ se1
04300	
04400	   
     

00100	SAILON NO. 57.2					SAIL   11-1
00200	
00300	                              SECTION 11
00400	                                    
00500	                           BASIC CONSTRUCTS
00600	                                    
00700	   
00800	   
00900	SYNTAX
01000	   
01100	   
01200	11-1.    
01300	
01400	<variable>               ::= <identifier>
01500	                         ::= <identifier> [ <subscript_list> ]
01600	                         ::= DATUM ( <item_identifier> )
01700	                         ::= DATUM ( <item_identifier> ) [ 
01800	                                <subscript_list> ] 
01900	
02000	<subscript_list>         ::= <algebraic_expression>
02100	                         ::= <subscript_list> , <algebraic_expression> 
02200	   
02300	   
02400	   
02500	SEMANTICS
02600	   
02700	Variables
02800	   
02900	   
03000	11-2.    If  a  variable  is  simply  an  identifier, it represents a
03100	single value of the type given in its declaration.
03200	   
03300	   
03400	11-3.     If it is an identifier qualified by  a  subscript  list  it
03500	represents  an  element  from  the  array  bearing  the  name  of the
03600	identifier.
     

00100	SAILON NO. 57.2					SAIL   11-4
00200	
00300	   
00400	   
00500	11-4.     The array should contain as many dimensions  as  there  are
00600	elements in the subscript list.  A[I] represents the I+1th element of
00700	the vector A (if the vector has a lower bound of 0).  B[I,J]  is  the
00800	element  from  the  I+1th row and J+1th column of the two-dimensional
00900	array B.  To explain the indexing scheme precisely, all arrays behave
01000	as  if  each  dimension  had its origin at 0, with (integral) indices
01100	extending infinitely far in either direction.  However, only the part
01200	of  an array between (and including) the lower and upper bounds given
01300	in the declaration are available for use (and in fact, these are  the
01400	only  parts  allocated).   If  the  array  is not declared SAFE, each
01500	subscript is tested against the bounds for its dimension.  If  it  is
01600	outside  its  range, a fatal message is printed identifying the array
01700	and subscript position at fault.  SAFE arrays are not bounds-checked.
01800	Users must take the consequences of the journeys of errant subscripts
01900	for SAFE arrays.  The bounds checking causes  at  least  three  extra
02000	machine  instructions  (two  of  which  are always executed for valid
02100	subscripts) to be added for each subscript in each  array  reference.
02200	The  algebraic  expressions  for  lower  and  upper  bounds  in array
02300	declarations, and for subscripts in subscripted variables, are always
02400	converted  to  Integer values (see Arithmetic Type Conversions, 9-21)
02500	before use.
02600	   
02700	   
02800	11-5.    For  more  information  about  the  implementation  of  SAIL
02900	arrays, see ARRAY IMPLEMENTATION, 17-35.
03000	   
03100	   
03200	Datums
03300	   
03400	   
03500	11-6.    If  the  Item argument of DATUM has an algebraic datum, this
03600	value is returned.  Otherwise the result is  representative  of  some
03700	other  data type and the value returned will have very little meaning
03800	as an algebraic value; it will probably be some internal  pointer  or
03900	something.   This  is mentioned here because there are times when the
04000	compiler will not be able to tell  that  such  a  type  mismatch  has
04100	occurred.   Then  it  will be up to the user to interpret the strange
04200	results.  If a Set is desired here, of course, the result  is  a  Set
04300	primary and may be used as such.
04400	   
04500	   
04600	Identifiers
04700	   
04800	   
04900	11-7.    You  will  notice  that  no  syntax  was  included  for  the
05000	non-terminal symbols <identifier> or <constant>.  It is far easier to
05100	explain these constructs in an informal manner.
     

00100	SAILON NO. 57.2					SAIL   11-8
00200	
00300	   
00400	   
00500	11-8.    A  SAIL  letter  is any of the upper or lower case letters A
00600	through Z, or the underline character  (_  or  !,  they  are  treated
00700	equivalently).   Lower case letters are mapped into the corresponding
00800	upper case letters for purposes of symbol table comparisons  (SCHLUFF
00900	is  the  same symbol as Schluff).  A digit is any of the characters 0
01000	through 9.  An identifier is a string of characters consisting  of  a
01100	letter  followed  by virtually any number of letters and digits There
01200	must be a character which is neither a letter nor a digit (nor either
01300	of the characters "." or "$") both before and after every identifier.
01400	In other words, if YOU can't determine where one identifier ends  and
01500	another begins in a program you have never seen before, well, neither
01600	can SAIL.
01700	   
01800	   
01900	11-9.    There is a  set  of  identifiers  which  are  used  as  SAIL
02000	delimiters  (in the Algol sense -- that is, BEGIN is treated by Algol
02100	as if it were a single character.  Such an approach is not practical,
02200	so  a  reserved  identifier  is  used).  These identifiers are called
02300	Reserved Words and may not be used for any purpose other  than  those
02400	given  explicitly  in  the syntax, or in declarations (DEFINES) which
02500	mask their reserved-word status over the scope of  the  declarations.
02600	E.g.,  "INTEGER BEGIN" is allowed, but a Synonym (see Synonyms, 3-55)
02700	should have been provided for BEGIN if any  new  blocks  are  desired
02800	within  this  one,  because  BEGIN  is ONLY an Integer in this block.
02900	Another set of identifiers have preset declarations -- these are  the
03000	execution  time  functions.   These  latter  identifiers  may also be
03100	redefined by the user; they behave as if  they  were  declared  in  a
03200	block   surrounding   the  outer  block.   A  list  of  reserved  and
03300	predeclared identifiers follows:
03400	   
03500	   
03600	Sail Reserved Words
03700	   
03800	   
03900	11-10.    
04000	   
04100	ABS AND ANY ARRAY ARRAY_PDL ASSOC BBPP  BEGIN  BOOLEAN  CASE  COMMENT
04200	CONTINUE  COP  CVI  CVN  DATUM DEFINE DELETE DIV DO DONE DPB ELSE END
04300	ENTRY EQV ERASE EXTERNAL FALSE FIRST FOR FOREACH FORTRAN FORWARD FROM
04400	GEQ  GO  GOTO IBP IDPB IF ILDB IN INF INTEGER INTER INTERNAL ISTRIPLE
04500	ITEM ITEMVAR LABEL LAND LDB LENGTH LEQ LET LIBRARY  LOAD_MODULE  LNOT
04600	LOP LOR LSH MAKE MAX MIN MOD NEEDNEXT NEQ NEXT NEW NEW_ITEMS NOT NULL
04700	OF OR OWN PHI  PNAMES  PRELOAD_WITH  PROCEDURE  PUT  QUICK_CODE  REAL
04800	RECURSIVE  REFERENCE  REMOVE  REQUIRE RETURN ROT SAFE SECOND SET SETC
04900	SETO SHORT SOURCE_FILE START_CODE STEP STRING STRING_PDL STRING_SPACE
05000	SUCH SYSTEM_PDL THAT THEN THIRD TO TRUE UNTIL VALUE WHILE XOR
     

00100	SAILON NO. 57.2					SAIL   11-11
00200	
00300	   
00400	   
00500	11-11.    Those  who use Stanford's "Global Model" compiler will also
00600	recognize:
00700	GLOBAL MESSAGE SEGMENT_FILE SEGMENT_NAME
00800	   
00900	   
01000	Sail Predeclared Identifiers
01100	   
01200	   
01300	11-12.    
01400	   
01500	ARRBLT ARRINFO ARRTRAN ARRYIN  ARRYOUT  BREAKSET  CALL  CLOSE  CLOSIN
01600	CLOSO  CLRBUF CODE CVASC CVD CVE CVF CVFIL CVG CVIS CVO CVOS CVS CVSI
01700	CVSIX CVSTR CVXSTR ENTER EQU FILEINFO GETCHAN GETFORMAT INCHRW INCHRS
01800	INCHSL  INCHWL  INSTR INSTRL INSTRS INPUT INTIN INTSCAN LINOUT LOOKUP
01900	MTAPE OPEN OUT OUTCHR OUTSTR  REALIN  REALSCAN  RELEASE  RENAME  SCAN
02000	SETBREAK  SETFORMAT STRBRK TTYIN TTYINL TTYINS WORDIN WORDOUT USERCON
02100	USERERR USETI USETO
02200	   
02300	   
02400	11-13.    These apply only  to  Stanford  users  (especially  "Global
02500	Model" users): BACKUP GET_BIT GET_DATA GET_ENTRY IFGLOBAL ISSUE LODED
02600	PTCHRS PTCHRW PTIFRE PTOCNT PTOCHS PTOCHW PTOSTR PTYALL PTYGET  PTYIN
02700	PTYREL PTYSTR PUT_DATA QUEUE
     

00100	SAILON NO. 57.2					SAIL   11-14
00200	
00300	   
00400	   
00500	11-14.    Some  of  the  reserved  words  are  equivalent  to certain
00600	special characters.  These equivalences are:
00700	
00800	
00900		CHARACTER		RESERVED WORD (s)
01000	
01100		    ∧			   AND
01200		    ≡			   EQV	
01300		    ¬			   NOT
01400		    ∨			   OR
01500		    ⊗			   XOR	
01600		    ∞			   INF
01700		    ε			   IN
01800		    |		           SUCH THAT
01900		    ≠			   NEQ
02000		    ≤			   LEQ
02100		    ≥			   GEQ
02200		    {			   SETO	   "set open"
02300		    }			   SETC	   "set close"
02400		    ∪			   UNION
02500		    ∩			   INTER
02600		    `			   ASSOC   for derived sets
02700		    ↔			   SWAP
02800		    _			   !	   alternate underline
02900	   
03000	   
03100	Arithmetic Constants
03200	   
03300	   
03400	11-15.    
03500	     12369 is an Integer with decimal value 12369
03600	     '12357 is an Integer constant with octal value 12357
03700	     123.  is a Real constant with floating point value 123.0
03800	     0123.0 is a Real constant with floating point value 123.0
03900	     .524 is a Real constant with floating point value 0.524
04000	     5.3@4 is a Real constant with floating point value 53000.0
04100	     5.342@-3 is a Real constant with value 0.005342
04200	   
04300	   
04400	11-16.    The character ' (right quote) precedes a string  of  digits
04500	to be converted into an OCTAL number.
     

00100	SAILON NO. 57.2					SAIL   11-17
00200	
00300	   
00400	   
00500	11-17.    If  a  .  or a @ appears in a numeric constant, the type of
00600	the constant is returned as Real (even if it has an integral  value).
00700	Otherwise  it  is  an  integer.  Type conversions are made at compile
00800	time to make the type of a constant commensurate with  that  required
00900	by  a  given  operation.   Expressions  involving  only constants are
01000	evaluated by the compiler and the resultant  values  are  substituted
01100	for the expressions.
01200	   
01300	   
01400	11-18.    The  reserved  word  TRUE  is  equivalent  to  the  Integer
01500	(Boolean) constant -1; FALSE is equivalent to the constant 0.
01600	   
01700	   
01800	String Constants
01900	   
02000	   
02100	11-19.    A String constant is a  string  of  ASCII  characters  (any
02200	which  you  can  get  into  a text file) delimited at each end by the
02300	character ".  If the " character is desired in the string, insert two
02400	" characters (after the initial delimiting " character, of course).
02500	   
02600	   
02700	11-20.    A  String  constant  behaves  like  any  other  (algebraic)
02800	primary.  It is originally of type String, but may  be  converted  to
02900	Integer   by   extracting  the  first  character  if  necessary  (see
03000	String-Arithmetic Conversions, 9-27).
03100	   
03200	   
03300	11-21.    The  reserved  word  NULL  represents  a  String   constant
03400	containing no characters (length=0).
     

00100	SAILON NO. 57.2					SAIL   11-22
00200	
00300	   
00400	   
00500	Examples
00600	   
00700	   
00800	11-22.    The  left  hand  column in the table that follows gives the
00900	required input format to obtain the strings given in  the  right-hand
01000	column:
01100	   
01200	      INPUT                          RESULT                 LENGTH
01300	   
01400	"THIS IS A STRING"             THIS IS A STRING             16
01500	"WHAT DOES ""FERNDOK"" MEAN?"  WHAT DOES "FERNDOK" MEAN?    25
01600	"THIS IS HOW YOU TYPE A """    THIS IS HOW YOU TYPE A "     24
01700	"""THIS IS A QUOTED STRING"""  "THIS IS A QUOTED STRING"    25
01800	""                                                          0
01900	NULL                                                        0
02000	   
02100	   
02200	   
02300	11-23.    The scanning algorithm is altered somewhat if the String is
02400	being used as a macro body definition (see USE OF DEFINE, 13-0).
02500	   
02600	   
02700	Comments
02800	   
02900	   
03000	11-24.    If   the   scanner  detects  the  identifier  COMMENT,  all
03100	characters up to  and  including  the  next  semicolon  (;)  will  be
03200	ignored.   A  comment may appear anywhere as long as the word COMMENT
03300	is properly delimited (not in a String constant, of course);
03400	   
03500	   
03600	11-25.    A string constant appearing just before  a  statement  also
03700	has the effect of a comment.
     

00100	SAILON NO. 57.2					SAIL   12-1
00200	
00300	                              SECTION 12
00400	                                    
00500	                       EXECUTION TIME ROUTINES
00600	                                    
00700	   
00800	   
00900	GENERAL
01000	   
01100	Scope
01200	   
01300	   
01400	12-1.    A   large  set  of  pre-declared,  built-in  procedures  and
01500	functions have been compiled into a library permanently  resident  on
01600	the  system disk area (SYS:LIBSAI.REL), and optionally into a special
01700	sharable write-protected high segment.   The  library  also  contains
01800	programs  for managing storage allocation and initialization, and for
01900	certain String functions.  If a user calls one of these procedures  a
02000	request is automatically made to the loader to include the procedure,
02100	and any other routines it might need, in the core image (or  to  link
02200	to  the  high  segment).   These  routines provide input/output (I/O)
02300	facilities, Arithmetic-String conversion  facilities,  array-handling
02400	procedures and miscellaneous other interesting functions.
02500	   
02600	   
02700	12-2.    The   remainder   of  this  section  describes  the  calling
02800	sequences and functions of these routines.
02900	   
03000	   
03100	Notational Conventions
03200	   
03300	   
03400	12-3.    A short-hand is used in these  descriptions  for  specifying
03500	the  types  (if  any)  of  the  execution-time  routines and of their
03600	parameters.  Before the description of each routine there is a sample
03700	call of the form
03800	
03900	
04000	   VALUE ← FUNCTION ( ARG1, ARG2, ... ARGn )
04100	
04200	If VALUE is omitted, the procedure is an untyped one, and may only be
04300	called at statement level (Procedure Statements, 6-2).
     

00100	SAILON NO. 57.2					SAIL   12-4
00200	
00300	   
00400	   
00500	12-4.    The types of VALUE and the arguments may be determined using
00600	the following scheme:
00700	
00800	  1)  If " characters surround the  sample  identifier  (which  is
00900	      usually  mnemonic  in nature) a String argument is expected.
01000	      Otherwise the  argument  is  Integer  or  Real.   If  it  is
01100	      important  which  of  the  types  Integer  or  Real  must be
01200	      presented, it will be made clear in the description  of  the
01300	      function.   Otherwise the compiler assumes Integer arguments
01400	      (for those functions which are predeclared).  The  user  may
01500	      pass Real arguments to these routines (WORDOUT, for example)
01600	      by re-declaring  them  in  the  blocks  in  which  the  Real
01700	      arguments are desired.
01800	
01900	  2)  If the @  character  precedes  the  sample  identifier,  the
02000	      argument  will  be  called  by reference.  Otherwise it is a
02100	      value parameter.
02200	   
02300	   
02400	Example
02500	   
02600	   
02700	12-5.    
02800	
02900	
03000	  "RESULT" ← SCAN ( @"SOURCE", BREAK_TABLE, @BRCHAR)
03100	
03200	is a predeclared procedure with the implicit declaration:
03300	
03400	  EXTERNAL STRING PROCEDURE SCAN (REFERENCE STRING SOURCE;
03500					  INTEGER BREAK_TABLE;
03600					  REFERENCE INTEGER BRCHAR);
03700	
03800	   
03900	   
04000	I/O ROUTINES
04100	                                    
04200	                                    
04300	                                 Open                                 ____                                     
04400	   
04500	   
04600	Form:
04700	   
04800	   
04900	12-6.    OPEN(CHANNEL,"DEVICE",MODE,NUMBER_OF_INPUT_BUFFERS,
05000	    NUMBER_OF_OUTPUT_BUFFERS,@COUNT,@BRCHAR,@EOF);
     

00100	SAILON NO. 57.2					SAIL   12-6
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-7.    SAIL input/output operates  at  a  very  low  level  in  the
00900	following sense: the operations necessary to obtain devices, open and
01000	close files, etc., are almost directly analogous to the system  calls
01100	used  in  assembly  language.   OPEN  is  used to associate a channel
01200	number (0 to '17) with a device, to determine the data  mode  of  the
01300	I/O to occur on this channel (character mode, binary mode, dump mode,
01400	etc.), to specify storage requirements for the data buffers  used  in
01500	the operations, and to provide the system with information to be used
01600	for input operations.
01700	          
01800	
01900	
02000	CHANNEL is a user-provided channel  number  which  will  be  used  in
02100	       subsequent I/O operations to identify the device.  CHANNEL may
02200	       range from 0 to 15 ('17).  If some file  is  already  open  on
02300	       this  channel,  a  RELEASE  will be performed for that channel
02400	       before the OPEN is executed.
02500	
02600	
02700	DEVICE must be a String (i.e.  "TTY", "DATA") which  is  recognizable
02800	       by the system as a physical or logical device name.
02900	
03000	
03100	MODE  is the data mode for the I/O operation.   MODE  0  will  always
03200	       work for characters ( see Input, 12-40 and Out, 12-45).  Modes
03300	       8 ('10) and 15 ('17) are applicable for binary  and  dump-mode
03400	       operations  using  the  functions  WORDIN, WORDOUT, ARRYIN, or
03500	       ARRYOUT (see Wordin, 12-48 and  following).   For  other  data
03600	       modes, see [Moorer].
03700	       If any of bits 18-21 are on in the MODE word, the I-O routines
03800	       will not print error messages when  data  errors  occur  which
03900	       present  the  corresponding  bits  as a response to the GETSTS
04000	       UUO.  Instead, the GETSTS bits will be reported to the user as
04100	       described  under EOF below.  If bit 23 is on, no error message
04200	       will be printed if  an  invalid  file  name  specification  is
04300	       presented  to LOOKUP, ENTER, or RENAME, a code identifying the
04400	       problem  will  be  returned  (see  Lookup,  Enter,  12-17  and
04500	       following,   Rename,   12-21   for  details).   If  you  don't
04600	       understand any of this, leave all non-mode  bits  off  in  the
04700	       MODE word.
     

00100	SAILON NO. 57.2					SAIL   12-7
00200	
00300	
00400	
00500	NUMBER_OF{INPUT/OUTPUT}_BUFFERS specifies the number of buffers to be
00600	       reserved for the I/O operations (see  [Moorer]  for  details).
00700	       At  least  one buffer must be specified for input if any input
00800	       is to be done in modes other than '17; similarly  for  output.
00900	       If  data  is  only  going  one  direction,  the  other  buffer
01000	       specification  should  be  0.   Two  buffers  give  reasonable
01100	       performance  for most devices (1 is sufficient for a TTY, more
01200	       are required for DSK if rapid operation is desired).
01300	       The left half of the BUFFER parameter, if non-zero,  specifies
01400	       the  buffer  size  for  the I/O buffers.  Use this only if you
01500	       desire non-standard sizes.
01600	   
01700	   
01800	12-8.    The  remaining  arguments  are  applicable  only  for  INPUT
01900	(String  input).   They  will  be  ignored  for  any other operations
02000	(although their values may be changed by the Open function).
02100	
02200	
02300	COUNT     designates a variable which will contain the maximum number
02400	          of  characters  to  be  read from "DEVICE" in a given INPUT
02500	          call (see Input, 12-40, Breakset, 12-22).  Fewer characters
02600	          may  be  read  if a break character is encountered or if an
02700	          end of file is detected.  The count should be a variable or
02800	          constant  (not an expression), since its address is stored,
02900	          and the temporary storage for an expression may be re-used.
03000	
03100	
03200	BRCHAR    designates a variable into which the break  character  (see
03300	          INPUT  and  BREAKSET  again) will be stored.  This variable
03400	          can  be  tested  to  determine  which  of   many   possible
03500	          characters terminated the read operation.
     

00100	SAILON NO. 57.2					SAIL   12-8
00200	
00300	
00400	
00500	EOF       designates a variable to be used for two purposes:
00600	
00700	   1)  If EOF is 0 when OPEN is called, a SAIL error message  will
00800	       be  invoked  if the device is not available.  The user will
00900	       be  given  the  options  of  retrying  or  terminating  the
01000	       operation.  If EOF is non-zero when OPEN is called, it will
01100	       be set to 0 if the OPEN is successful.  Otherwise  it  will
01200	       not  be  changed.   In  this  case  (EOF non-zero on entry)
01300	       control will be returned to the user.  This flag  may  then
01400	       be tested.
01500	
01600	   2)  EOF will  be  made  non-zero  (TRUE)  if  an  end  of  file
01700	       condition,  or any error condition among those enabled (see
01800	       MODE, above)  is  detected  during  any  SAIL  input/output
01900	       operation.   It  will  be  0  (FALSE) on return to the user
02000	       otherwise.  Subsequent inputs  after  an  EOF  return  will
02100	       return  non-zero values in EOF and a null String result for
02200	       INPUT.  For ARRYIN , a 0 is returned as the  value  of  the
02300	       call  after  end of file is detected.  If EOF is TRUE after
02400	       such an operation, it will contain the entire set (18 bits)
02500	       of  GETSTS  information  in  the left half.  The EOF bit is
02600	       '20000, and is the only one you'll ever see if you  haven't
02700	       specially  enabled  for  others.   A  summary of the enable
02800	       bits, the  EOF  and  error  bits,  and  their  meanings  is
02900	       contained  in  the  Appendix  NON-FATAL  ERROR, EXCEPTIONAL
03000	       CONDITION RETURN CODES, 18-11.
03100	   
03200	   
03300	Assembly Language Approximation to OPEN
03400	   
03500	   
03600	12-9.    
03700	        INIT    CHANNEL,MODE
03800	        SIXBIT  /DEVICE/
03900	        XWD     OHED,IHED
04000	        JRST    <handle error condition>
04100	        JUMPE   <NUMBER_OF_OUTPUT_BUFFERS>,GETIN
04200	        <allocate buffer space>
04300	        OUTBUF  CHANNEL,NUMBER_OF_OUTPUT_BUFFERS
04400	GETIN:  JUMPE   <NUMBER_OF_INPUT_BUFFERS>,DONE
04500	        <allocate buffer space>
04600	        INBUF   CHANNEL,NUMBER_OF_INPUT_BUFFERS
04700	DONE:   <mark channel open -- internal bookkeeping>
04800	        <return>
04900	   
05000	OHED:   BLOCK   3
05100	IHED:   BLOCK   3
     

00100	SAILON NO. 57.2					SAIL   12-9
00200	
00300	                                    
00400	                                    
00500	                         Close, Closin, Closo                         ____________________                             
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-10.    
01200	CLOSE ( CHANNEL )
01300	CLOSIN ( CHANNEL )
01400	CLOSO ( CHANNEL )
01500	   
01600	Function:
01700	   
01800	   
01900	12-10.    The input (CLOSIN) or output (CLOSO) side of the  specified
02000	channel is closed: all output is forced out (CLOSO); the current file
02100	name is forgotten.  However the device is still active; no OPEN  need
02200	be done again before the next input/output operation.  No INPUT, OUT,
02300	etc.  may be given to a directory device until an ENTER,  LOOKUP,  or
02400	RENAME has been issued for the channel.
02500	   
02600	   
02700	12-11.    CLOSE  is  equivalent  to  the execution of both CLOSIN and
02800	CLOSO for the channel.
02900	                                    
03000	                                    
03100	                               Getchan                               _______                                    
03200	   
03300	   
03400	Form:
03500	   
03600	   
03700	12-12.    VALUE ← GETCHAN;
03800	   
03900	   
04000	Function:
04100	   
04200	   
04300	12-13.    The number of some channel not currently open is  returned.
04400	-1 is returned if all channels are busy.
     

00100	SAILON NO. 57.2					SAIL   12-14
00200	
00300	                                    
00400	                                    
00500	                               Release                               _______                                    
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-14.    RELEASE ( CHANNEL );
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-15.    If  an  OPEN has been executed for this channel, a CLOSE is
01800	now executed for it.  The device is dissociated from the channel  and
01900	returned  to  the  resource  pool (unless it has been assigned by the
02000	monitor ASSIGN command).  No I/O operation may refer to this  channel
02100	until another OPEN denoting it has been executed.
02200	   
02300	   
02400	12-16.    Release  is  always valid.  If the channel mentioned is not
02500	currently open, the command is simply ignored.
02600	                                    
02700	                                    
02800	                            Lookup, Enter                            _____________                                 
02900	   
03000	   
03100	Form:
03200	   
03300	   
03400	12-17.    
03500	LOOKUP ( CHANNEL , "FILE" , @FLAG );
03600	ENTER ( CHANNEL , "FILE" , @FLAG );
03700	   
03800	   
03900	Function:
04000	   
04100	   
04200	12-18.    Before input or output operations may be  performed  for  a
04300	directory device (DECtape or DSK) a file name must be associated with
04400	the channel on which the device has been  opened  (see  Open,  12-6).
04500	LOOKUP names a file which is to be read.  ENTER names a file which is
04600	to be created or extended (see [Moorer]).  Both operations are  valid
04700	even  if  no filename is really necessary.  It is recommended that an
04800	ENTER be performed after every OPEN  of  an  output  device  so  that
04900	output  not  normally  directed  to the DSK can be directed there for
05000	later processing if desired.  The format for a file name string is
     

00100	SAILON NO. 57.2					SAIL   12-18
00200	
00300	
00400		NAME ,
00500		NAME.EXT ,
00600		NAME[P,PN] ,
00700	   or   NAME.EXT[P,PN] (see [Moorer] for the meaning of these things
00800				if you do not immediately understand).
00900	
01000	All characters are converted to SIXBIT by moving the '100 bit to  the
01100	'40 bit.  SAIL is not as choosy about the characters it allows as PIP
01200	and other processors are.  Any character which is not ".", ",",  "[",
01300	or  "]"  will  be  converted  and passed on.  Up to 6 characters from
01400	NAME, 3 from EXT, P, or PN will be converted -- the rest are ignored.
01500	   
01600	   
01700	12-19.    If the LOOKUP or ENTER operation fails (see [Moorer])  then
01800	variable  FLAG may be examined to determine the cause.  The left half
01900	of FLAG will be set to '777777 (Flag has  the  logical  value  TRUE).
02000	The  right  half  will contain the code returned by the system giving
02100	the cause of the failure.  An invalid file specification will  return
02200	a  code  of  '10.   In this case, if the appropriate bit (bit 23, see
02300	OPEN) was OFF in the MODE parameter of the  OPEN,  an  error  message
02400	will   be  printed;  otherwise,  the  routine  just  returns  without
02500	performing the UUO.
02600	   
02700	   
02800	12-20.    If the LOOKUP or ENTER succeeds, FLAG will be set  to  zero
02900	(FALSE).
03000	                                    
03100	                                    
03200	                                Rename                                ______                                    
03300	   
03400	   
03500	Form:
03600	   
03700	   
03800	12-21.    RENAME ( CHANNEL , "FILE-SPEC" , PROTECTION , @FLAG );
     

00100	SAILON NO. 57.2					SAIL   12-22
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-22.    The  file  open  on CHANNEL is renamed to FILE_SPEC (a NULL
00900	file-name  will  delete  the  file)  with  read/write  protection  as
01000	specified  in  PROTECTION  (nine  bits, described in the time-sharing
01100	manual).  FLAG is set as in LOOKUP and ENTER.
01200	                                    
01300	                                    
01400	                               Breakset                               ________                                   
01500	   
01600	   
01700	Form:
01800	   
01900	   
02000	12-22.    BREAKSET( TABLE, "BREAK_CHARS" , MODE);
02100	   
02200	   
02300	Function:
02400	   
02500	   
02600	12-23.    Character input/output is done using the String features of
02700	SAIL.   In  fact, I/O is the chief justification for the existence of
02800	strings in the language.
02900	    String input presents a problem not  present  in  String  output.
03000	The length of an output String can be used to determine the number of
03100	characters written.  However  it  is  often  awkward  to  require  an
03200	absolute  count  for  input.  Quite often one would like to terminate
03300	input, or "break", when one of  a  specified  set  of  characters  is
03400	encountered  in  the  input  stream.   In  SAIL,  this  capability is
03500	implemented  by  means  of  the  BREAKSET,  INPUT,  TTYIN,  and  SCAN
03600	functions.
03700	   
03800	   
03900	12-24.    The  value  of TABLE may range from 1 to 18.  Thus up to 18
04000	different sets of break specifications may exist at once.  Which  set
04100	will be used is determined by the TABLE parameter in an INPUT or SCAN
04200	function call.
04300	   
04400	   
04500	12-25.    The function of a given BREAKSET  command  depends  on  the
04600	MODE,  an  integer  which  is  interpreted as a right-justified ASCII
04700	character whose value is intended to be vaguely  mnemonic.   BREAKSET
04800	commands can be partitioned into 3 groups according to mode:
     

00100	SAILON NO. 57.2					SAIL   12-26
00200	
00300	   
00400	   
00500	GROUP 1 -- Break character specifications
00600	   
00700	   
00800	12-26.    
00900	
01000	
01100	MODE     FUNCTION
01200	
01300	
01400	"I"      (by Inclusion) The characters in the  BREAK_CHARS  String
01500	          comprise  the  set of characters which will terminate an
01600	          INPUT (or SCAN).
01700	
01800	
01900	"X"      (by eXclusion) Only those characters (of the possible 128
02000	          ASCII  characters) which are NOT contained in the String
02100	          BREAK_CHARS will terminate  an  input  when  using  this
02200	          table.
02300	
02400	
02500	"O"      (Omit) The characters in "BREAK_CHARS"  will  be  omitted
02600	          (deleted) from the input string.
02700	   
02800	   
02900	12-27.    Any  "I"  or  "X"  command  completely  specifies the break
03000	character set for its table (i.e., the table is  reset  before  these
03100	characters  are  stored  in  it).   Neither  will destroy the omitted
03200	character set currently specified for this table.   Any  "O"  command
03300	completely  specifies the set of omitted characters, without altering
03400	the break characters for the table in question.  If a character is  a
03500	break-character,  any  role  it might play as an omitted character is
03600	sacrificed.
03700	   
03800	   
03900	12-28.    The second group of MODEs  determines  the  disposition  of
04000	break  characters in the input stream.  The "BREAK_CHARS" argument is
04100	ignored in these commands, and may in fact be NULL:
04200	   
04300	   
     

00100	SAILON NO. 57.2					SAIL   12-29
00200	
00300	   
00400	   
00500	GROUP 2 -- Break character disposition
00600	   
00700	   
00800	12-29.    
00900	
01000	
01100	MODE     FUNCTION
01200	
01300	
01400	"S"      (Skip -- default mode) After execution of an "S"  command
01500	          the  break  character  will  not  appear  either  in the
01600	          resultant String or in subsequent INPUTs or SCANs--  the
01700	          character  is  "skipped".   Its  value may be determined
01800	          after the INPUT by examination of  the  break  character
01900	          variable (see Open, 12-6).
02000	
02100	
02200	"A"      (Append) The break character (if  there  is  one  --  see
02300	          Open,   12-6   and   Input,   12-40)   is  appended,  or
02400	          concatenated to the end of the input  string.   It  will
02500	          not appear again in subsequent inputs.
02600	
02700	
02800	"R"      (Retain) The break  character  does  not  appear  in  the
02900	          resultant  INPUT  or  SCAN String, but will be the first
03000	          character processed in the next operation  referring  to
03100	          this input source (file or SCAN String).
03200	   
03300	   
03400	12-30.    For  disk  and tape files using the standard editor format,
03500	line numbers present a special problem.  A  line  number  is  a  word
03600	containing  5  ASCII characters representing the number in bits 0-34,
03700	with a "1" in bit 35.  No other words in the file contain 1's in  bit
03800	35.   Since  String  manipulations  provide no way for distinguishing
03900	line numbers from other characters, there must be a way to  warn  the
04000	user  that  line  numbers are present, or to allow him to ignore them
04100	entirely.
04200	   
04300	   
04400	12-31.    The third group of  MODEs  determines  the  disposition  of
04500	these line numbers.  Again, the "BREAK_CHARS" argument is ignored:
04600	   
04700	   
     

00100	SAILON NO. 57.2					SAIL   12-32
00200	
00300	   
00400	   
00500	Group 3 -- Line number disposition
00600	   
00700	   
00800	12-32.    
00900	
01000	
01100	MODE     FUNCTION
01200	
01300	
01400	"P"      (Pass -- default) Line numbers are treated as  any  other
01500	          characters.   Their identity is lost; they simply appear
01600	          in the result string.
01700	
01800	
01900	"N"      (No numbers) No line number  (or  the  TAB  which  always
02000	          follows  it in standard files) will appear in the result
02100	          string.  They are simply discarded.
02200	
02300	
02400	"L"      (Line no.  break) The result String  will  be  terminated
02500	          early  if  a line number is encountered.  The characters
02600	          comprising the line number and the associated  TAB  will
02700	          appear  as  the  next  6 characters read or scanned from
02800	          this  character  source.   The  user's  break  character
02900	          variable  (see  Open, 12-6 and Input, 12-40) will be set
03000	          to -1 to indicate a line number break.
03100	
03200	
03300	"E"       (lee  Erman's  very  own  mode)  The  result  String  is
03400	          terminated on a line number as with "L", but neither the
03500	          line number nor the TAB  following  it  will  appear  in
03600	          subsequent  inputs.   The  line number word, negated, is
03700	          returned in the user's (integer) BRCHAR variable.
03800	
03900	
04000	"D"      (Display) If the TTY is a DPY, each line number from  any
04100	          input  file will be displayed (along with a page number)
04200	          on the right-hand side of the screen.  This mode  really
04300	          applies  to  all  input operations after the "D" operand
04400	          appears in any Breakset call.  There is no way  to  turn
04500	          it off.
04600	   
04700	   
04800	12-33.    Once  a  break  table is set up, it may be referenced in an
04900	INPUT, TTYIN or SCAN call to control the scanning operation.
     

00100	SAILON NO. 57.2					SAIL   12-33
00200	
00300	   
00400	   
00500	Example:
00600	   
00700	   
00800	12-34.    To  delimit  a  "word"  a  program  might  wish  to   input
00900	characters until a blank, a TAB, a line feed, a comma, or a semicolon
01000	is encountered, ignoring line numbers.   Assume  also  that  carriage
01100	returns  are  to  be  ignored,  and that the break character is to be
01200	retained in the character source for the next scanning operation:
01300	
01400	
01500	    BREAKSET(DELIMS," ,;"&TAB&LF,"I"); Comment break on any of these; 
01600	    BREAKSET(DELIMS,'15,"O"); Comment ignore carriage return;
01700	    BREAKSET(DELIMS,NULL,"N"); Comment ignore line numbers;
01800	    BREAKSET(DELIMS,NULL,"R"); Comment save break char for next time;
01900	
02000	                                    
02100	                                    
02200	                               Setbreak                               ________                                   
02300	   
02400	   
02500	Form:
02600	   
02700	   
02800	12-35.    
02900	   
03000	SETBREAK ( TABLE , "BREAK_CHARS" , "OMIT_CHARS" , "MODES" )
03100	   
03200	   
03300	Function:
03400	   
03500	   
03600	12-36.    SETBREAK is logically equivalent to the SAIL statement:
03700	
03800	
03900	BEGIN "SETBREAK"
04000	 INTEGER I;
04100	 
04200	 IF LENGTH(OMIT_CHARS) > 0 THEN
04300		BREAKSET(TABLE,OMIT_CHARS,"O");
04400	
04500	 FOR I←1 STEP 1 UNTIL LENGTH(MODES) DO
04600		BREAKSET(TABLE,BREAK_CHARS,MODES[I FOR 1])
04700	
04800	END "SETBREAK"
04900	
     

00100	SAILON NO. 57.2					SAIL   12-36
00200	
00300	                                    
00400	                                    
00500	                                Stdbrk                                ______                                    
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-37.     STDBRK ( CHANNEL );
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-38.    Eighteen   breakset   tables   have   been   selected    as
01800	representative  of  the  more  common input scanning operations.  The
01900	function STDBRK initializes the breakset tables by opening  the  file
02000	SYS:BKTBL.BKT  on  CHANNEL and reading in these tables.  The user may
02100	then reset those tables which he does not like to something  he  does
02200	like.
02300	   
02400	   
02500	12-39.    The  eighteen  tables  are  described  here  by  giving the
02600	SETBREAKs which would be required for the user to initialize them:
02700	
02800	
02900	DELIMS ← '15 & '12 & '40 & '11 & '14;
03000	 Comment carriage return, line feed, space, tab, form feed;
03100	LETTS ← "ABC ... Zabc ... z_";
03200	DIGS ← "0123456789";
03300	SAILID ← LETTS&DIGS;
03400	
03500	SETBREAK ( 1, '12, '15, "INS" );
03600	SETBREAK ( 2, '12, NULL, "INA" );
03700	SETBREAK ( 3, DELIMS, NULL, "XNR" );
03800	SETBREAK ( 4, SAILID, NULL, "INS" );
03900	SETBREAK ( 5, SAILID, NULL, "INR" );
04000	SETBREAK ( 6, LETTS, NULL, "XNR" );
04100	SETBREAK ( 7, DIGS, NULL, "XNR" );
04200	SETBREAK ( 8, DIGS, NULL, "INS" );
04300	SETBREAK ( 9, DIGS, NULL, "INR" );
04400	SETBREAK (10, DIGS&"+-@.", NULL, "XNR" );
04500	SETBREAK (11, DIGS&"+-@.", NULL, "INS" );
04600	SETBREAK (12, DIGS&"+-@.", NULL, "INR" );
04700	SETBREAK (13-18, NULL, NULL, NULL );
04800	
     

00100	SAILON NO. 57.2					SAIL   12-39
00200	
00300	                                    
00400	                                    
00500	                                Input                                _____                                     
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-40.    "RESULT" ← INPUT(CHANNEL, BREAK_TABLE);
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-41.    A string of characters is obtained for  the  file  open  on
01800	CHANNEL,  and  is  returned  as  the  result.  The INPUT operation is
01900	controlled by BREAK_TABLE (see Breakset,  12-22)  and  the  reference
02000	variables  BRCHAR,  EOF,  and COUNT which are provided by the user in
02100	the OPEN function for this channel (see Open, 12-6).   Input  may  be
02200	terminated  in several ways.  The exact reason for termination can be
02300	obtained by examining BRCHAR and EOF:
     

00100	SAILON NO. 57.2					SAIL   12-41
00200	
00300	                  
00400	
00500	
00600	EOF    BRCHAR    
00700	
00800	
00900	≠0     0       End of file or an error (if enabled, see Open, 12-6
01000	               occurred  while  reading.   The  result is a String
01100	               containing   all   non-omitted   characters   which
01200	               remained in the file when INPUT was called.
01300	
01400	
01500	0      0       No break characters were encountered.   The  result
01600	               is  a  String  of length equal to the current COUNT
01700	               specifications for the CHANNEL (see Open, 12-6).
01800	
01900	
02000	0      <0      A line number was encountered and the  break  table
02100	               specified  that someone wanted to know.  The result
02200	               String contains  all  characters  up  to  the  line
02300	               number.   If mode "L" was specified in the Breakset
02400	               setting up this table, bit 35 is turned off in  the
02500	               line  number  word  so  that  it will be input next
02600	               time.  -1 is placed in BRCHAR.   If  mode  "E"  was
02700	               specified,  the  line number will not appear in the
02800	               next input String, but  its  negated  ASCII  value,
02900	               complete  with  low-order  line number bit, will be
03000	               found in BRCHAR.
03100	
03200	
03300	0      >0      A  break  character  was  encountered.   The  break
03400	               character is stored in BRCHAR (an INTEGER reference
03500	               variable, see  Open,  12-6)  as  a  right-justified
03600	               7-bit ASCII value.  It may also be tacked on to the
03700	               end of the result String or saved  for  next  time,
03800	               depending  on  the  BREAKSET  mode  (see  Breakset,
03900	               12-22).
04000	   
04100	   
04200	12-42.    If break table  0  is  specified,  the  only  criteria  for
04300	termination  are  end  of  file  or COUNT exhaustion.  The routine is
04400	somewhat faster operating in this mode.
     

00100	SAILON NO. 57.2					SAIL   12-43
00200	
00300	                                    
00400	                                    
00500	                                 Scan                                 ____                                     
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-43.    "RESULT" ← SCAN ( @"SOURCE" , BREAK_TABLE , @BRCHAR )
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-44.    SCAN functions identically  to  INPUT  with  the  following
01800	exceptions:
01900	
02000	
02100	1.   The source is not a data file but the String  SOURCE,  called
02200	     by  reference.   The String SOURCE is truncated from the left
02300	     to produce the same effect as one would obtain if SOURCE were
02400	     a  data  file.  The disposition of the break character is the
02500	     same as it is for INPUT.
02600	
02700	
02800	2.   BRCHAR is directly specified as a parameter.  INPUT gets  its
02900	     break character variable from a table set up by Open, 12-6.
03000	
03100	
03200	3.   Line number considerations are irrelevant.
03300	                                    
03400	                                    
03500	                                 Out                                 ___                                      
03600	   
03700	   
03800	Form:
03900	   
04000	   
04100	12-45.    OUT(CHANNEL,"STRING")
04200	   
04300	Function:
04400	   
04500	   
04600	12-45.    STRING is output to the  file  open  on  CHANNEL.   If  the
04700	device is a TTY, the String will be typed immediately.  Buffered mode
04800	text output is employed for this operation.  The data mode  specified
04900	in  the  OPEN for this channel must be 0 or 1.  The EOF variable will
05000	be set non-zero as described in Open, 12-6 if an  error  is  detected
05100	and the program is enabled for it; 0 otherwise.
     

00100	SAILON NO. 57.2					SAIL   12-45
00200	
00300	                                    
00400	                                    
00500	                                Linout                                ______                                    
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-46.    LINOUT ( CHANNEL , NUMBER );
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-47.    ABS(NUMBER) mod 100,000 is converted to a 5 character ASCII
01800	string.  These characters are placed in a single word in  the  output
01900	file  designated  by CHANNEL with the low-order bit (line-number bit)
02000	turned on.  A tab is inserted after the line number.   Mode  0  or  1
02100	must  have been specified in the OPEN (Open, 12-6) for the results to
02200	be anywhere near satisfactory.  EOF is set as in OUT.
02300	                                    
02400	                                    
02500	                                Wordin                                ______                                    
02600	   
02700	   
02800	Form:
02900	   
03000	   
03100	12-48.    VALUE ← WORDIN ( CHANNEL )
03200	   
03300	   
03400	Function:
03500	   
03600	   
03700	12-49.    The next word from the file open on CHANNEL is returned.  A
03800	0 is returned, and EOF (see Open, 12-6,Input, 12-40) set, when end of
03900	file or  error  is  encountered.   This  operation  is  performed  in
04000	buffered  mode  or  dump mode, depending on the mode specification in
04100	the OPEN.
04200	                                    
04300	                                    
04400	                                Arryin                                ______                                    
04500	   
04600	   
04700	Form:
04800	   
04900	   
05000	12-50.     ARRYIN ( CHANNEL , @LOC , HOW_MANY );
     

00100	SAILON NO. 57.2					SAIL   12-50
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-51.    HOW_MANY words are read from the device and  file  open  on
00900	CHANNEL,   and   deposited   in  memory  starting  at  location  LOC.
01000	Buffered-mode input is done if MODE (see Open, 12-6) is '10  or  '14.
01100	Dump-mode  input  is  done  if  MODE  is '16 or '17.  Other modes are
01200	illegal.
01300	   
01400	   
01500	12-52.    If an end of file or enabled error condition occurs  before
01600	HOW_MANY  words are read, the EOF variable (see Open, 12-6) is set to
01700	the enabled bits in its left half, as usual.  Its right half contains
01800	the number of words actually read.  EOF will be 0 if the full request
01900	is satisfied.
02000	                                    
02100	                                    
02200	                               Wordout                               _______                                    
02300	   
02400	   
02500	Form:
02600	   
02700	   
02800	12-53.    WORDOUT ( CHANNEL , VALUE );
02900	   
03000	   
03100	Function:
03200	   
03300	   
03400	12-54.    VALUE is placed in  the  output  buffer  for  CHANNEL.   An
03500	OUTPUT  is done when the buffer is full or when a CLOSE or RELEASE is
03600	executed for this channel.  Dump mode output will  be  done  if  dump
03700	mode  is  specified  in  the OPEN (see Open, 12-6).  EOF is set as in
03800	OUT.
03900	                                    
04000	                                    
04100	                               Arryout                               _______                                    
04200	   
04300	   
04400	Form:
04500	   
04600	   
04700	12-55.     ARRYOUT ( CHANNEL , @LOC , HOW_MANY );
     

00100	SAILON NO. 57.2					SAIL   12-56
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-56.    HOW_MANY  words  are  written  from  memory,  starting   at
00900	location  LOC, onto the device and file open on channel CHANNEL.  The
01000	valid modes are again '10, '14, '16, and '17.  The  EOF  variable  is
01100	set as in ARRYIN, except that the EOF bit itself will never occur.
01200	                                    
01300	                                    
01400	                                Mtape                                _____                                     
01500	   
01600	   
01700	Form:
01800	   
01900	   
02000	12-57.    MTAPE ( CHANNEL , MODE );
02100	   
02200	   
02300	Function:
02400	   
02500	   
02600	12-58.    MTAPE  is ignored unless the device associated with CHANNEL
02700	is a magnetic tape drive.  It performs tape actions as follows:
02800	             
02900	             
03000	          MODE               FUNCTION
03100	             
03200	          "A"                Advance past one tape mark (or file)
03300	          "B"                Backspace past one tape mark
03400	          "E"                Write tape mark
03500	          "F"                Advance one record
03600	          "R"                Backspace one record
03700	          "S"                Write 3 inches of blank tape
03800	          "T"                Advance to logical end of tape
03900	          "U"                Rewind and unload
04000	          "W"                Rewind tape
04100	             
     

00100	SAILON NO. 57.2					SAIL   12-59
00200	
00300	                                    
00400	                                    
00500	                             Useti, Useto                             ____________                                 
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-59.    
01200	USETI ( CHANNEL , VALUE );
01300	USETO (CHANNEL , VALUE );
01400	   
01500	   
01600	Function:
01700	   
01800	   
01900	12-60.    The corresponding  system  function  is  carried  out  (see
02000	[Moorer] ).
02100	                                    
02200	                                    
02300	                            Realin, Intin                            _____________                                 
02400	   
02500	   
02600	Form:
02700	   
02800	   
02900	12-61.    
03000	VALUE ← REALIN ( CHANNEL );
03100	VALUE ← INTIN ( CHANNEL );
03200	   
03300	   
03400	Function:
03500	   
03600	   
03700	12-62.     Number input may be obtained using the functions REALIN or
03800	INTIN, depending on whether a Real number or an Integer is  required.
03900	Both  functions use the same free field scanner, and take as argument
04000	a channel number.
04100	   
04200	   
04300	12-63.    Free  field  scanning  works  as  follows:  characters  are
04400	scanned   one  at  a  time  from  the  input  channel.   Nulls,  line
04500	numbers,and carriage returns are ignored.  When a digit is scanned it
04600	is assumed that this is a number and the following syntax is used:
04700	
04800	<number>         ::=	<sign><real number>
04900	
05000	<real number>	 ::=	<decimal number>|<decimal number><exponent>|
05100				<exponent>
     

00100	SAILON NO. 57.2					SAIL   12-63
00200	
00300	
00400	
00500	<decimal number> ::=	<integer>|<integer>.|<integer>.<integer>|
00600				.<integer>
00700	
00800	<integer>	 ::=	<digit>|<integer><digit>
00900	
01000	
01100	<exponent>	 ::=	@<sign><integer>
01200	
01300	<digit>		 ::=	0|1|2|3|4|5|6|7|8|9
01400	
01500	<sign>		 ::=	+|-|<empty>
01600	
01700	
01800	   
01900	   
02000	12-64.    If  the digit is not part of a number an error message will
02100	be printed and the program will halt.  Typing a carriage return  will
02200	cause the input function to return zero.  On input, leading zeros are
02300	ignored.  The ten most  significant  digits  are  used  to  form  the
02400	number.   A  check  for  overflow  and underflow is made and an error
02500	message printed if this occurs.  When using  INTIN  any  exponent  is
02600	removed  by  scaling  the  Integer  number.  Rounding is used in this
02700	process.   All  numbers  are  accurate  to  one  half  of  the  least
02800	significant bit.
02900	   
03000	   
03100	12-65.    After scanning the number the last delimiter is replaced on
03200	the input string and is returned  as  the  break  character  for  the
03300	channel.   If  no  number is found, a zero is returned, and the break
03400	variable is set to -1; If an end of file or enabled error  is  sensed
03500	this  is  also  returned  in  the  appropriate  channel variable.  The
03600	maximum character count appearing in the OPEN call is ignored.
03700	                                    
03800	                                    
03900	                          Realscan, Intscan                          _________________                               
04000	   
04100	   
04200	Form:
04300	   
04400	   
04500	12-66.    
04600	VALUE ← REALSCAN ( @"NUMBER_STRING" , @BRCHAR ) ; VALUE ←  INTSCAN  (
04700	@"NUMBER_STRING" , @BRCHAR );
     

00100	SAILON NO. 57.2					SAIL   12-67
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-67.    These  functions  are  identical  in function to REALIN and
00900	INTIN.  Their inputs, however, are obtained from their  NUMBER_STRING
01000	arguments.    These   routines  replace  NUMBER_STRING  by  a  string
01100	containing all characters left over after the number has been removed
01200	from the front.
01300	                                    
01400	                                    
01500	                        Teletype I/O Functions                        ______________________                            
01600	   
01700	   
01800	Form:
01900	   
02000	   
02100	12-68.    
02200	CHAR ← INCHRW;
02300	CHAR ← INCHRS;
02400	"STR" ← INCHWL;
02500	"STR" ← INCHSL ( @FLAG );
02600	"STR" ← INSTR ( BRCHAR );
02700	"STR" ← INSTRL ( BRCHAR );
02800	"STR" ← INSTRS ( @FLAG , BRCHAR );
02900	"STR" ← TTYIN ( TABLE , @BRCHAR );
03000	   
03100	"STR" ← TTYINL ( TABLE , @BRCHAR );
03200	"STR" ← TTYINS ( TABLE , @BRCHAR );
03300	OUTCHR ( CHAR );
03400	OUTSTR ( "STR" );
03500	CLRBUF;
03600	BACKUP;
03700	LODED ( "STR" );
     

00100	SAILON NO. 57.2					SAIL   12-69
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-69.    Each  of  the  I/O  functions  uses  the TTYUUO UUO's to do
00900	direct TTY I/O.
01000	
01100	INCHRW   waits for a  character  to  be  typed  and  returns  that
01200	         character.
01300	
01400	INCHRS   returns a negative  value  if  no  characters  have  been
01500	         typed; otherwise it is INCHRW.
01600	
01700	INCHWL   waits for a line, terminated  by  a  carriage-return  and
01800	         line  feed  (CR-LF)  to be typed.  It returns as a string
01900	         all characters up to (not including) the CR.  The  LF  is
02000	         lost.
02100	
02200	INCHSL   returns NULL with FLAG ≠ 0 if no lines have  been  typed.
02300	         Otherwise it sets FLAG to 0 and performs INCHWL.
02400	
02500	INSTR    returns as  a  string  all  characters  up  to,  but  not
02600	         including,  the  first  instance  of  BRCHAR.  The BRCHAR
02700	         instance is lost.
02800	
02900	INSTRL   waits for a line to be typed, then performs INSTR.
03000	
03100	INSTRS   is INCHSL if no lines are waiting; INSTRL otherwise.
03200	
03300	TTYIN    uses the break  table  features  described  in  Breakset,
03400	         12-22  and  Input,  12-40  to  return  a string and break
03500	         character.  Mode "R" is illegal; line  number  modes  are
03600	         irrelevant.   The  input count (see Open, 12-6) is set at
03700	         100.
03800	
03900	TTYINL   waits for a line to be typed, then does TTYIN.
04000	
04100	TTYINS   sets BRCHAR to ≠0  and  returns  NULL  if  no  lines  are
04200	         waiting.  Otherwise it is TTYINL.
     

00100	SAILON NO. 57.2					SAIL   12-69
00200	
00300	
00400	OUTCHR   types  its  character  argument  (right-justified  in  an
00500	         integer variable).
00600	
00700	OUTSTR   types its string argument.
00800	
00900	CLRBUF   flushes the input buffer.
01000	
01100	BACKUP   backs up the scan (when started by a system command).
01200	
01300	LODED    loads the line editor with the string argument.
01400	                                    
01500	                                    
01600	              Pseudo-teletype functions (Stanford only)              _________________________________________                   
01700	   
01800	   
01900	Form:
02000	   
02100	   
02200	12-70.    
02300	line ← PTYGET ;
02400	PTYREL ( line );
02500	characteristics ← PTGETL ( line );
02600	PTSETL ( line , characteristics );
02700	number ← PTIFRE ( line );
02800	number ← PTOCNT ( line );
02900	char ← PTCHRW ( line );
03000	char ← PTCHRS ( line );
03100	PTOCHS ( line , char );
03200	PTOCHW ( line , char );
03300	PTOSTR ( line , "str" );
03400	string ← PTYALL ( line );
03500	string ← PTYSTR ( line , brchar );
03600	string ← PTYIN ( line, bktbl , @brchar );
     

00100	SAILON NO. 57.2					SAIL   12-71
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-71.    
00900	
01000	PTYGET   gets a new pseudo-teletype line number  and  returns  it.
01100	         The global variable .SKIP.  is -1 if the attempt to get a
01200	         PTY was successful, and 0 otherwise.
01300	
01400	PTYREL   releases PTY identified by "line".
01500	
01600	PTGETL   returns line characteristics for the PTY.
01700	
01800	PTSETL   sets  line  characteristics  for  thm  PTY  specified  by
01900	         "line".
02000	
02100	PTIFRE   returns the number of free characters in  the  PTY  input
02200	         buffer.
02300	
02400	PTOCNT   returns the number of free characters in the  PTY  output
02500	         buffer.
02600	
02700	PTCHRW   waits for a character from the PTY and returns it.
02800	
02900	PTCHRS   reads a character from the PTY if there is  one,  returns
03000	         -1 if none.
03100	
03200	PTOCHS   tries to send a character to a PTY.  If the  attempt  was
03300	         successful,  the global variable .SKIP.  is -1, otherwise
03400	         0.
03500	
03600	PTOCHW   sends a character to a PTY, waiting if necessary.
03700	
03800	PTOSTR   sends the string to the PTY, waiting if necessary.
     

00100	SAILON NO. 57.2					SAIL   12-71
00200	
00300	
00400	PTYALL   returns whatever is  in  the  PTY's  output  buffer.   No
00500	         waiting is done.
00600	
00700	PTYSTR   reads characters from  the  PTY,  waiting  if  necessary,
00800	         until  a  character equal to "char" is seen.  All but the
00900	         break character is returned as the string.  If the  break
01000	         character   was  '15  (carriage  return),  the  following
01100	         line-feed is snarfed.
01200	
01300	PTYIN    reads from the PTY (waiting if  necessary)  according  to
01400	         break  table  conventions.  The break character is stored
01500	         in "brchar".
01600	            
01700	   
01800	   
01900	STRING MANIPULATION ROUTINES
02000	                                    
02100	                                    
02200	                                 Equ                                 ___                                      
02300	   
02400	   
02500	Form:
02600	   
02700	   
02800	12-73.    VALUE ← EQU ( "STR1", "STR2" );
02900	   
03000	   
03100	Function:
03200	   
03300	   
03400	12-74.    The value of this function is TRUE if  STR1  and  STR2  are
03500	equal  in length and have identically the same characters in them (in
03600	the same order).  The value of EQU is FALSE otherwise.
03700	   
03800	   
03900	TYPE CONVERSION ROUTINES
04000	                                    
04100	                                    
04200	                              Setformat                              _________                                   
04300	   
04400	   
04500	Form:
04600	   
04700	   
04800	12-75.     SETFORMAT ( WIDTH , DIGITS ) ;
     

00100	SAILON NO. 57.2					SAIL   12-76
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-76.    This function allows specification of a minimum  width  for
00900	strings  created  by  the functions CVS, CVOS, CVE, CVF, and CVG (see
01000	Cvs, 12-80 and following).   If  this  number  (WIDTH)  is  positive,
01100	enough  blanks  will  be inserted in front of the resultant string to
01200	make the entire results at least WIDTH characters long.  The sign, if
01300	any,  will  appear  after  the blanks.  If WIDTH is negative, leading
01400	zeroes will be used in place of blanks, The  sign,  of  course,  will
01500	appear  before  the  zeroes.   This  parameter  is initialized by the
01600	system to 0.
01700	   
01800	   
01900	12-77.    In addition, the DIGITS parameter allows one to specify the
02000	number  of  digits  to  appear following the decimal point in strings
02100	created by CVE, CVF, and CVG.  This number is initially 7.   See  the
02200	writeups  on  the  functions  Cve,  Cvf, Cvg, 12-92 and following for
02300	details.
02400	                                    
02500	                                    
02600	                              Getformat                              _________                                   
02700	   
02800	   
02900	Form:
03000	   
03100	   
03200	12-78.    GETFORMAT ( @WIDTH , @DIGITS ) ;
03300	   
03400	   
03500	Function:
03600	   
03700	   
03800	12-79.    The  WIDTH  and  DIGIT  settings  specified  in  the   last
03900	SETFORMAT call are returned in the appropriate reference parameters.
04000	                                    
04100	                                    
04200	                                 Cvs                                 ___                                      
04300	   
04400	   
04500	Form:
04600	   
04700	   
04800	12-80.    "ASCII_STRING" ← CVS ( VALUE );
     

00100	SAILON NO. 57.2					SAIL   12-81
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-81.    The  decimal Integer representation of VALUE is produced as
00900	an ASCII String with leading zeroes omitted (unless  WIDTH  has  been
01000	set  by  Setformat,  12-75  to  some  negative  value).   "-" will be
01100	concatenated to the String representing the decimal absolute value of
01200	VALUE if VALUE is negative.
01300	                                    
01400	                                    
01500	                                 Cvos                                 ____                                     
01600	   
01700	   
01800	Form:
01900	   
02000	   
02100	12-82.    "ASCII_STRING" ← CVOS ( VALUE );
02200	   
02300	   
02400	Function:
02500	   
02600	   
02700	12-83.    The octal Integer representation of VALUE is produced as an
02800	ASCII String with leading zeroes omitted (unless WIDTH has  been  set
02900	to  some negative value by Setformat, 12-75).  No "-" will be used to
03000	indicate negative numbers.  For instance, -5 will be  represented  as
03100	"777777777773".
03200	                                    
03300	                                    
03400	                                 Cvis                                 ____                                     
03500	   
03600	   
03700	Form:
03800	   
03900	   
04000	12-84.    "STRING" ← CVIS ( ITEM , @FLAG ) ;
04100	   
04200	   
04300	Function:
04400	   
04500	   
04600	12-85.    The  print name of ITEM is returned as a string.  An Item's
04700	print name is the identifier used to declare it, or that provided  by
04800	the  NEW_PNAME function (see New_Pname, 12-88).  FLAG is set to FALSE
04900	(0) if the appropriate string is found.  Otherwise it is set to  TRUE
05000	(-1), and you should not place great faith in the string result.
     

00100	SAILON NO. 57.2					SAIL   12-85
00200	
00300	                                    
00400	                                    
00500	                                 Cvsi                                 ____                                     
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-86.    ITEM ← CVSI ( "PNAME" , @FLAG ) ;
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-87.    The  Item  whose identifier (or name provided by New_Pname,
01800	12-88) is the same as the string argument PNAME is returned and  FLAG
01900	set  to  FALSE  if  such  an  Item exists.  Otherwise, something very
02000	random is returned, and FLAG is set to TRUE.
02100	                                    
02200	                                    
02300	                              New_Pname                              _________                                   
02400	   
02500	   
02600	Form:
02700	   
02800	   
02900	12-88.    
03000	NEW_PNAME (ITEM , "STRING" )
03100	   
03200	   
03300	Function:
03400	   
03500	   
03600	12-89.    This function assigns to the Item the name "STRING".  Don't
03700	perform  this  twice  for  the  same  Item without first deleting the
03800	previous one.  The corresponding name or Item may be retrieved  using
03900	CVIS or CVSI (above).  You must use the REQUIRE n PNAMES construct in
04000	one of the files comprising your program for all this to work.
04100	                                    
04200	                                    
04300	                              Del_Pname                              _________                                   
04400	   
04500	   
04600	Form:
04700	   
04800	   
04900	12-90.    
05000	DEL_PNAME ( ITEM )
     

00100	SAILON NO. 57.2					SAIL   12-90
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-91.    This function deletes any string PNAME associated with this
00900	Item.
01000	                                    
01100	                                    
01200	                            Cve, Cvf, Cvg                            _____________                                 
01300	   
01400	   
01500	Form:
01600	   
01700	   
01800	12-92.    
01900	"STRING"  ← CVE ( VALUE ); "STRING" ← CVF ( VALUE ); "STRING" ← CVG (
02000	VALUE );
02100	   
02200	   
02300	Function:
02400	   
02500	   
02600	12-93.     Real number output is facilitated by means of one of three
02700	functions CVE,CVG, or CVF, corresponding to the E,G, and F formats of
02800	FORTRAN IV.  Each of these functions takes as argument a real  number
02900	and  returns  a  string.   The  format of the string is controlled by
03000	another function SETFORMAT (  WIDTH,DIGITS)  (see  Setformat,  12-75)
03100	which  is  used  to  change  WIDTH from zero and DIGITS from 7, their
03200	initial values.  WIDTH specifies the minimum string length.  If WIDTH
03300	is  positive  leading blanks will be inserted and if negative leading
03400	zeros will be inserted.
03500	   
03600	   
03700	12-94.    The following table indicates the strings returned for some
03800	typical numbers.  _ indicates a space and it is assumed that WIDTH←10
03900	and DIGITS←3.
04000	
04100		   CVF    	   CVE    	   CVG
04200		______.000	__.100@-3_	__.100@-3_
04300		______.001	__.100@-2_	__.100@-2_
04400		______.010	__.100@-1_	__.100@-1_
04500		______.100	__.100____	__.100____
04600		_____1.000	__.100@1__	__1.00____
04700		____10.000	__.100@2__	__10.0____
04800		___100.000	__.100@3__	__100.____
04900		__1000.000	__.100@4__	__.100@4__
     

00100	SAILON NO. 57.2					SAIL   12-94
00200	
00300	
00400		_10000.000	__.100@5__	__.100@5__
00500	       _100000.000	__.100@6__	__.100@6__
00600	      _1000000.000	__.100@7__	__.100@7__
00700	      -1000000.000	_-.100@7__	_-.100@7__
00800	
00900	   
01000	   
01100	12-95.    The first character ahead of the number is either  a  blank
01200	or a minus sign.  With WIDTH←-10 plus and minus 1 would print as:
01300	
01400		   CVF    	   CVE    	   CVG
01500		_00001.000	_0.100@1__	_01.00____
01600		-00001.000	-0.100@1__	-01.00____
01700	
01800	   
01900	   
02000	12-96.    All  numbers  are accurate to one unit in the eighth digit.
02100	If DIGITS is greater than 8, trailing zeros  are  included;  if  less
02200	than eight, the number is rounded.
02300	                                    
02400	                                    
02500	                                Cvstr                                _____                                     
02600	   
02700	   
02800	Form:
02900	   
03000	   
03100	12-97.    "STRING" ← CVSTR ( VALUE ) ;
03200	   
03300	   
03400	Function:
03500	   
03600	   
03700	12-98.    VALUE  is treated as a 5-character left-justified word full
03800	of ASCII.  the result is a 5-character long String  containing  these
03900	characters.  The low order bit of VALUE is ignored.
04000	                                    
04100	                                    
04200	                                Cvxstr                                ______                                    
04300	   
04400	   
04500	Form:
04600	   
04700	   
04800	12-99.     "STRING" ← CVXSTR ( VALUE ) ;
     

00100	SAILON NO. 57.2					SAIL   12-100
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-100.    VALUE is treated as a 6-character left-justified word full
00900	of SIXBIT.  The result is a 6-character long String containing  these
01000	characters, converted to ASCII.
01100	                                    
01200	                                    
01300	                                 Cvd                                 ___                                      
01400	   
01500	   
01600	Form:
01700	   
01800	   
01900	12-101.    VALUE ← CVD ( "ASCII_STRING" );
02000	   
02100	   
02200	Function:
02300	   
02400	   
02500	12-102.    ASCII_STRING   should   be   a  String  of  decimal  ASCII
02600	characters perhaps preceded by plus and/or minus  signs.   Characters
02700	with  ASCII  values  ≤  SPACE ('40) are ignored preceding the number.
02800	Any character not a digit will  terminate  the  conversion  (with  no
02900	error indication).  The result is the internal (signed) 36-bit binary
03000	representation of the number.
03100	                                    
03200	                                    
03300	                                 Cvo                                 ___                                      
03400	   
03500	   
03600	Form:
03700	   
03800	   
03900	12-103.    VALUE ← CVO ( "ASCII_STRING" );
04000	   
04100	   
04200	Function:
04300	   
04400	   
04500	12-104.    This function is the same as CVD  except  that  the  input
04600	characters are deemed to represent Octal values.
     

00100	SAILON NO. 57.2					SAIL   12-104
00200	
00300	                                    
00400	                                    
00500	                                Cvasc                                _____                                     
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-105.     VALUE ← CVASC ( "STRING" );
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-106.    This  is the inverse function for CVSTR.  Up to five ASCII
01800	characters will be fetched from the beginning of  STRING  and  placed
01900	left-justified  in VALUE.  If the String is less than five characters
02000	long, the right characters will be padded with null (0) characters.
02100	                                    
02200	                                    
02300	                                Cvsix                                _____                                     
02400	   
02500	   
02600	Form:
02700	   
02800	   
02900	12-107.     VALUE ← CVSIX ( "STRING" );
03000	   
03100	   
03200	Function:
03300	   
03400	   
03500	12-108.    The inverse for CVXSTR, this function works  the  same  as
03600	CVASC  except  that  up to six SIXBIT characters are placed in VALUE.
03700	The characters from STRING are converted from ASCII to SIXBIT  before
03800	depositing them in VALUE.
03900	                                    
04000	                                    
04100	                                Cvfil                                _____                                     
04200	   
04300	   
04400	Form:
04500	   
04600	   
04700	12-109.     VALUE ← CVFIL ( "FILE_SPEC" , @EXTEN , @PPN ) ;
     

00100	SAILON NO. 57.2					SAIL   12-110
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-110.    FILE_SPEC  has  the same form as a file name specification
00900	for LOOKUP or ENTER.  The SIXBIT for the file  name  is  returned  in
01000	VALUE.   SIXBIT  values  for  the  extension  and  project-programmer
01100	numbers are returned in the  respective  reference  parameters.   Any
01200	unspecified  portions  of  the  FILE_SPEC will result in zero values.
01300	The global variable _SKIP_ (accessed  by  declaring  it  as  EXTERNAL
01400	INTEGER  _SKIP_)  will  be  0 if no errors occurred, ≠0 if an invalid
01500	file name specification is presented.
01600	   
01700	Arrinfo
01800	   
01900	   
02000	Form:
02100	   
02200	   
02300	12-110.     VALUE ← ARRINFO ( ARRAY , PARAMETER );
02400	   
02500	   
02600	Function:
02700	   
02800	   
02900	12-111.    
03000	
03100	ARRINFO(ARRAY,-1)  returns the number of dimensions for the array.
03200	                   This number is negative for String arrays.
03300	
03400	ARRINFO(ARRAY,0)   returns the total size of the array in words.
03500	
03600	ARRINFO(ARRAY,1)    returns  the  lower  bound   for   the   first
03700	                   dimension.
03800	
03900	ARRINFO(ARRAY,2)    returns  the  upper  bound   for   the   first
04000	                   dimension.
04100	
04200	ARRINFO(ARRAY,3)    returns  the  lower  bound  for   the   second
04300	                   dimension.
04400	
04500	ARRINFO( ...)      etc.
     

00100	SAILON NO. 57.2					SAIL   12-112
00200	
00300	                                    
00400	                                    
00500	                                Arrblt                                ______                                    
00600	   
00700	   
00800	Form:
00900	   
01000	   
01100	12-112.     ARRBLT ( @LOC1 , @LOC2 , NUM );
01200	   
01300	   
01400	Function:
01500	   
01600	   
01700	12-113.    NUM  words  are  transferred  from  consecutive  locations
01800	starting  at  LOC2  to  consecutive  locations  starting at LOC1.  No
01900	bounds checking is performed.  This function does not work  well  for
02000	String Arrays.
02100	                                    
02200	                                    
02300	                               Arrtran                               _______                                    
02400	   
02500	   
02600	Form:
02700	   
02800	   
02900	12-114.     ARRTRAN ( ARRAY1, ARRAY2 );
03000	   
03100	   
03200	Function:
03300	   
03400	   
03500	12-115.    This  function  copies  information from ARRAY2 to ARRAY1.
03600	The transfer starts at the  first  data  word  of  each  array.   The
03700	minimum  of  the  sizes  of  ARRAY1 and ARRAY2 is the number of words
03800	transferred.
03900	   
04000	   
04100	LIBERATION-FROM-SAIL ROUTINES
04200	                                    
04300	                                    
04400	                                 Code                                 ____                                     
04500	   
04600	   
04700	Form:
04800	   
04900	   
05000	12-116.     RESULT ← CODE ( INSTR , @ADDR )
     

00100	SAILON NO. 57.2					SAIL   12-116
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-117.    This function is equivalent to the FAIL statements:
00900	
01000	
01100		EXTERNAL .SKIP.		;DECLARE AS _SKIP_ IN SAIL
01200		SETOM	.SKIP.		;ASSUME SKIP
01300		MOVE	0,INSTR
01400		ADDI	0,@ADDR
01500		XCT	0
01600		SETZM	.SKIP.		;DIDN'T SKIP
01700		RETURN	(1)
01800	
01900	   
02000	In other words, it executes the  instruction  formed  by  adding  the
02100	address  of  the  ADDR  variable  (passed by reference) to the number
02200	INSTR.  Before the operation is carried out, AC1  is  loaded  from  a
02300	special  cell (initially 0).  AC1 is returned as the result, and also
02400	stored back into the special cell after the instruction is  executed.
02500	The  global  variable  _SKIP_  (.SKIP.   in DDT or FAIL) is FALSE (0)
02600	after the call  if  the  executed  instruction  did  not  skip;  TRUE
02700	(currently    -1)    if   it   did.    Declare   this   variable   as
02800	EXTERNAL INTEGER _SKIP_ if you want to use it.
02900	                                    
03000	                                    
03100	                                 Call                                 ____                                     
03200	   
03300	   
03400	Form:
03500	   
03600	   
03700	12-118.    RESULT ← CALL ( VALUE , "FUNCTION" );
     

00100	SAILON NO. 57.2					SAIL   12-119
00200	
00300	   
00400	   
00500	Function:
00600	   
00700	   
00800	12-119.    This function is equivalent to the FAIL statements:
00900	
01000	
01100		EXTERNAL .SKIP.
01200		SETOM	.SKIP.
01300		MOVE	1,VALUE
01400		CALL	1,[SIXBIT /FUNCTION/]
01500		SETZM	.SKIP.		;DID NOT SKIP
01600		RETURN	(REGISTER 1)
01700	
01800	The .SKIP.  variable (_SKIP_ in SAIL) is  set  as  described  in  the
01900	previous paragraph (CODE).
02000	                                    
02100	                                    
02200	                               Usercon                               _______                                    
02300	   
02400	   
02500	Form:
02600	   
02700	   
02800	12-120.    
02900	USERCON ( @INDEX , @VALUE , FLAG )
03000	   
03100	   
03200	Function:
03300	   
03400	   
03500	12-121.    This  function  allows  inspection  and  alteration of the
03600	"User Table" (see User  Table,  17-1).   Declare  an  index  you  are
03700	interested in as an External Integer (e.g., EXTERNAL INTEGER REMCHR).
03800	This will, when loaded, give an address which  is  secretly  a  small
03900	Integer  index  into  the User Table.  When passed by reference, this
04000	index is available to USERCON.  The names and meanings of the various
04100	User  Table  indices  can  be  found  in the file HEAD, wherever SAIL
04200	compiler program text files are sold.
04300	   
04400	   
04500	12-122.    USERCON  always  returns  the   current   value   of   the
04600	appropriate  User Table entry (the Global Upper Segment Table is used
04700	if FLAG is negative and your system knows  about  such  things).   If
04800	FLAG  is  odd, the contents of VALUE before the call replaces the old
04900	value in the selected entry of the selected table.
     

00100	SAILON NO. 57.2					SAIL   12-123
00200	
00300	   
00400	   
00500	12-123.    By now the incredible  danger  of  this  feature  must  be
00600	apparent  to  you.   Be  sure you understand the ramifications of any
00700	changes you make to any User Table value.
00800	                                    
00900	                                    
01000	                               Usererr                               _______                                    
01100	   
01200	   
01300	Form:
01400	   
01500	   
01600	12-124.    USERERR ( VALUE , CODE , "MSG" );
01700	   
01800	   
01900	Function
02000	   
02100	   
02200	12-125.    MSG is printed on the teletype.  If CODE  =  2,  VALUE  is
02300	printed  in  decimal  on  the  same  line.  Then on the next line the
02400	"LAST SAIL CALL" message is typed which indicates where in  the  user
02500	program  the error occurred.  A "?" or "→" character is typed and the
02600	user may type a standard reply (see ERROR MESSAGES, 14-19).  If  CODE
02700	is  1  or  2,  a  "→"  will be typed and execution will be allowed to
02800	continue.  If it is 0, a "?" is typed, and no  continuation  will  be
02900	permitted.
03000	                                    
03100	                                    
03200	                                Point                                _____                                     
03300	   
03400	   
03500	Form:
03600	   
03700	   
03800	12-126.    VALUE  ← POINT ( BYTE SIZE , @EFFECTIVE ADDRESS , LAST BIT
03900	NUMBER )
04000	   
04100	   
04200	Function:
04300	   
04400	   
04500	12-127.    POINT  returns  a  byte  pointer  (hence  it  is  of  type
04600	integer).  The three arguments are enough to specify the three fields
04700	of a PDP-10 If the LAST BIT  NUMBER  is  -1,  POINT  creates  a  byte
04800	pointer  which,  when  used with an ILDB, will pick up the first byte
04900	from the word at EFFECTIVE ADDRESS.  Otherwise, the  three  arguments
05000	to  POINT  are  exactly  analogous to the three arguments to POINT in
05100	FAIL.
     

00100	SAILON NO. 57.2					SAIL   13-1
00200	
00300	                              SECTION 13
00400	                                    
00500	                            USE OF DEFINE
00600	                                    
00700	The SAIL DEFINE feature provides  a  limited  macro  capability  with
00800	parameter substitution.  The formal syntax for DEFINE declarations is
00900	given in DECLARATIONS, 3-1.  Use of these macros is described below.
01000	   
01100	   
01200	Defining Macros
01300	   
01400	   
01500	13-1.    When a macro of the form
01600	
01700		DEFINE MAC(X,Y) = "FOR Y←1 STEP 1 UNTIL X DO"
01800	
01900	is seen by the compiler (either at  declaration  level  or  statement
02000	level),  it  first associates with the "formal parameters" sequential
02100	indices (X=1, Y=2).  Then it reads the String  constant  representing
02200	the macro body into String space, substituting for each occurrence of
02300	a formal parameter the  character  '177  followed  by  the  character
02400	representing  the  index  of  this  formal  parameter.  These special
02500	characters will be used to locate  the  actual  parameters  when  the
02600	macro  is expanded.  The modified macro body is stored under the name
02700	of the macro, where it lies dormant until someone mentions it again.
02800	   
02900	   
03000	13-2.    In  what  follows,  the  character  ¬  will  represent   the
03100	character  ('177)  used  to identify parameter locations.  The number
03200	following it will always be the parameter index.  The above macro  is
03300	stored as:
03400	
03500	     FOR ¬2←1 STEP 1 UNTIL ¬1 DO
03600	
03700	   
03800	   
03900	13-3.    A macro may be re-defined (at statement level) as many times
04000	as desired.  The new macro body replaces the old  one.   Macro  names
04100	follow  block  structure,  so  for a macro with the same name as some
04200	other macro to be a redefinition, it must appear at  the  same  block
04300	level as that other definition.
     

00100	SAILON NO. 57.2					SAIL   13-4
00200	
00300	   
00400	   
00500	String Constants in Macro Bodies
00600	   
00700	   
00800	13-4.    String constants may be represented in macro bodies, but two
00900	quote characters (") must be inserted for each  one  which  would  be
01000	necessary  if  the  String  constant  appeared outside the macro body
01100	(which after all is itself a String constant, hence the problem).
01200	   
01300	   
01400	Using Macros
01500	   
01600	   
01700	13-5.    When a macro name (ignore for the moment the possibility  of
01800	parameters)  is  detected  in  a  file,  the  body  of  that macro is
01900	retrieved and becomes the input to the SAIL scanner until the  String
02000	is  exhausted;  the  scanner  then returns to the source file for its
02100	input.  The macro name itself never makes it out of the scanner.  If,
02200	while  a  macro  body  is  providing  input,  another  macro  name is
02300	encountered, the original macro body is  put  aside  until  this  new
02400	macro is exhausted.  Nesting may occur to any level; however, it will
02500	be necessary to increase the size of the compiler's DEFINE push  down
02600	stack  if nesting gets extremely deep ( see the D switch in Switches,
02700	14-13).
02800	   
02900	   
03000	Macro Parameters
03100	   
03200	   
03300	13-6.    If a macro body has been defined with formal parameters, the
03400	compiler will look for actual parameters to satisfy them when a macro
03500	is expanded.  Actual parameters follow the macro name, are surrounded
03600	by parentheses and separated by commas.
     

00100	SAILON NO. 57.2					SAIL   13-7
00200	
00300	   
00400	   
00500	13-7.    A macro parameter is scanned as a String constant.  However,
00600	for convenience, the following special rules apply to the scanning of
00700	a macro actual parameter:
00800	   
00900	
01000	  1)  All blank characters after the left parenthesis are ignored.
01100	
01200	  2)  If the first non-blank character is not the " character, the
01300	      parameter  String  will  be terminated by a comma or a right
01400	      parenthesis, which will not appear in the parameter.  If the
01500	      "  character  is  subsequently  found,  it is treated as any
01600	      other text character.
01700	
01800	  3)  If the first non-blank character is  the  "  character,  the
01900	      parameter  is  scanned  using  the  normal  rules for String
02000	      constants.
02100	   
02200	   
02300	Example
02400	   
02500	   
02600	13-8.    
02700	
02800		MAC("I","J") is equivalent to MAC(I,J);
02900		MAC("J+3" , "X&""A STRING""")
03000		  is equivalent to MAC(J+3,X&"A STRING");
03100	
03200	 but	MAC("""A STRING""","PROC(I,J)") 
03300	
03400	may not be abbreviated, because the meaning of the " character  would
03500	otherwise  be  ambiguous  in  the  first argument, and the commas and
03600	parentheses need protection in the second.
03700	   
03800	   
03900	Actual Parameter Expansion
04000	   
04100	   
04200	13-9.    The actual parameter strings are stored in an  ordered  list
04300	just before the input stream is switched to the macro body.  When one
04400	of the ¬number pairs appears, the input stream  is  switched  to  the
04500	(number)th   actual   parameter.    Other  macros  (with  or  without
04600	parameters) may appear in these actual parameters  without  confusing
04700	the scanner (sic).
     

00100	SAILON NO. 57.2					SAIL   13-10
00200	
00300	   
00400	   
00500	13-10.    For  an  actual  parameter to be recognized eventually as a
00600	String constant, enough " characters must surround it to allow one to
00700	survive  on  each end when it passes through the scanner for the last
00800	time.  To be sure, the implementation of this feature is so  wondrous
00900	that  even  the  authors  must resort to trial and error methods when
01000	complicated things are done\enod\attempted.
01100	   
01200	   
01300	Examples
01400	   
01500	   
01600	13-11.    
01700	
01800	
01900	DEFINE TTY="1", SRC="2", BRK_ON_LFD="2";
02000		Comment for constant parameters for which
02100		  it is desirable to include symbolic names,
02200		  this is more efficient than assigning the
02300		  parameter values to variables;
02400	
02500	DEFINE TYPE(MSG)= "OUT(TTY,MSG)";
02600		Comment note inclusion of TTY macro in the
02700		  body of the TYPE macro;
02800	
02900	DEFINE TYPEC(MSG)="OUT(TTY,""MSG"")";
03000		Comment argument always to be made into
03100		  a String constant;
03200	
03300	DEFINE DEBUGGING = "TRUE", INP1(VBL,WHERE)=
03400	 "BEGIN
03500	   VBL←INPUT(SRC,BREAK_ON_LFD);
03600	   IF DEBUGGING THEN
03700		TYPE(""""""INPUT TO VBL AT WHERE IS""""&VBL"");
03800	  END"; Comment (probably);
03900	
04000	
04100	Using these definitions,
04200		
04300		INP1(STR,INITIAL READ) expands to:
04400	
04500		BEGIN
04600		 STR←INPUT(2,2);
04700		 IF TRUE THEN
04800			OUT(1,"INPUT TO STR AT INITIAL READ IS "&STR);
04900		END;
05000	
05100	   
     

00100	SAILON NO. 57.2					SAIL   14-1
00200	
00300	                              SECTION 14
00400	                                    
00500	                          COMPILER OPERATION
00600	                                    
00700	   
00800	   
00900	COMMAND FORMAT
01000	   
01100	Syntax
01200	   
01300	   
01400	14-1.    
01500	
01600	<command_line>           ::= <binary_name> <listing_name> ← 
01700	                                <source_list>
01800	                         ::= <file_spec> @
01900	                         ::= <file_spec> EXC 
02000	
02100	<binary_name>            ::= <file_spec>
02200	                         ::= <empty> 
02300	
02400	<listing_name>           ::= , <file_spec>
02500	                         ::= <empty> 
02600	
02700	<source_list>            ::= <file_spec>
02800	                         ::= <source_list> , <file_spec> 
02900	
03000	<file_spec>              ::= <file_name> <file_ext> <proj_prog>
03100	                         ::= <device_name> <file_spec> <switches>
03200	                         ::= <device_name> <switches> 
03300	
03400	<file_name>              ::= <legal_sixbit_id> 
03500	
03600	<file_ext>               ::= . <legal_sixbit_id>
03700	                         ::= <empty> 
03800	
03900	<proj_prog>              ::= [ <legal_sixbit_id> , <legal_sixbit_id> ]
04000	                         ::= <empty> 
04100	
04200	<device_name>            ::= <legal_sixbit_id> 
04300	
04400	<switches>               ::= ( <unslashed_switch_list> )
04500	                         ::= <slashed_switch_list>
04600	                         ::= <empty> 
04700	
04800	<unslashed_switch_list>  ::= <switch_spec>
04900	                         ::= <unslashed_switch_list> <switch_spec> 
     

00100	SAILON NO. 57.2					SAIL   14-1
00200	
00300	
00400	<slashed_switch_list>    ::= / <switch_spec>
00500	                         ::= <slashed_switch_list> / <switch_spec> 
00600	
00700	<switch_spec>            ::= <valid_switch_name>
00800	                         ::= <signed_integer> <valid_switch_name> 
00900	
01000	<valid_switch_name>      ::= D
01100	                         ::= L
01200	                         ::= M
01300	                         ::= P
01400	                         ::= Q
01500	                         ::= R
01600	                         ::= S
01700	                         ::= C
01800	                         ::= F 
01900	   
02000	   
02100	   
02200	Semantics
02300	   
02400	   
02500	14-2.    All this is by way of saying that SAIL accepts  commands  in
02600	essentially  the same format accepted by DEC processors such as MACRO
02700	and FORTRAN.  The binary file name is the name of the  output  device
02800	and  file  on which the ready to load object program will be written.
02900	The listing file, if included, will contain  a  copy  of  the  source
03000	files  with  a  header  at  the top of each page and an octal program
03100	counter entry at the head of each line (see Listing Features, 14-13).
03200	The  listing  file  name  is often omitted (no listing created).  The
03300	source file list specifies a set of user-prepared files  which,  when
03400	concatenated, form a valid SAIL program (one outer block).
03500	   
03600	   
03700	14-3.    legal_sixbit_identifier is a name which is acceptable to the
03800	time sharing system as a valid file  name,  device  name,  extension,
03900	etc.   when  its  first  six  (device,  file)  or  three  (extension,
04000	project-programmer number) are converted from ASCII to  SIXBIT.   For
04100	more information about file and device names, see [Moorer].
04200	   
04300	   
04400	14-4.    If  file_ext  is omitted from the binary_name, the extension
04500	for the output file will be .REL.   The  default  extension  for  the
04600	listing file is .LST.  SAIL will first try to find source files under
04700	the names given.  If this fails, and the extension  is  omitted,  the
04800	same file with a .SAI extension will be tried.
     

00100	SAILON NO. 57.2					SAIL   14-5
00200	
00300	   
00400	   
00500	14-5.    If device_name is omitted, DSK: is assumed.  If proj_prog is
00600	omitted, the project-programmer number for the job is assumed.
00700	   
00800	   
00900	14-6.    Switches are parameters which affect the  operation  of  the
01000	compiler.   A  list  of switches may appear after any file name.  The
01100	parameters specified are changed  immediately  after  the  file  name
01200	associated  with them is processed.  The meanings of the switches are
01300	given below.
01400	   
01500	   
01600	14-7.    The binary,  listing  and  (first)  source  file  names  are
01700	processed  before  compilation  -- subsequent source names (and their
01800	switches) are processed whenever an end-of-file condition is detected
01900	in  the current source file.  Source files which appear after the one
02000	containing the outer block's END delimiter are ignored.
02100	   
02200	   
02300	14-8.    Each new line in the  command  file  (or  entered  from  the
02400	teletype)  specifies  a  separate program compilation.  Any number of
02500	programs can be compiled by the same SAIL core image.
02600	   
02700	   
02800	14-9.    The file_spec@ command  causes  the  compiler  to  open  the
02900	specified  file  as  the command file.  Subsequent commands will come
03000	from this file.  If any of  these  commands  is  file_spec@,  another
03100	switch will occur.
03200	   
03300	   
03400	14-10.    The  file_spec! command will cause the specified file to be
03500	run as the next processor.  This program  will  be  started  in  "RPG
03600	mode".   That  is,  it will look on the disk for its commands if its
03700	standard command file is there --  otherwise,  command  control  will
03800	revert  to  the  TTY.  The default option for this file name is .DMP.
03900	The default device is SYS.
04000	   
04100	   
04200	14-11.    For information about logging in, running jobs, and so  on,
04300	see [Moorer].
     

00100	SAILON NO. 57.2					SAIL   14-12
00200	
00300	   
00400	   
00500	Rpg Mode
00600	   
00700	   
00800	14-12.    The  COMPILE,  DEBUG,  LOAD,  and  EXECUTE  set  of  system
00900	commands may be used to compile and run SAIL programs.  See  [Moorer]
01000	for  details.   A  typical  command  String to the system (which will
01100	prepare commands of the form described above and pass  them  to  SAIL
01200	(after starting it) might be:
01300	
01400	   DEBUG /SAIL RECOG(-2L5MRR)=BEG+PROCS+RECOG/LIST,CMDSCN[1,DCS]
01500	
01600	This command will cause the following commands to be placed in a file
01700	on your area by the name of QQSAIL.RPG:
01800	
01900	   RECOG.REL,RECOG.LST(-2L5MRR)←BEG,PROCS,RECOG
02000	   CMDSCN.REL←CMDSCN[1,DCS]
02100	   LOADER!
02200	
02300	The /SAIL entry may be omitted if all files have  a  .SAI  extension.
02400	The  loader  will  load the files with DDT or RAID and then start the
02500	specified debugging program.
     

00100	SAILON NO. 57.2					SAIL   14-13
00200	
00300	   
00400	   
00500	Switches
00600	   
00700	   
00800	14-13.    The following table describes the SAIL parameter  switches.
00900	If  the  switch letter is preceded in the table by the D character, a
01000	decimal number is expected as an argument.  0 is the  default  value.
01100	The  character  O indicates that an octal number is expected for this
01200	switch.  Otherwise the argument is ignored.
01300	
01400	ARG   SWITCH  FUNCTION
01500	
01600	      C       This switch turns on CREFfing.  The listing file (which
01700	              must exist) will be in a format suitable for processing
01800	              by  CREF,   the   program   which   will   generate   a
01900	              cross-reference listing of your SAIL program.
02000	
02100	      D       For every occurrence of  this  switch  in  the  command
02200	              line,  the amount of space for the push down stack used
02300	              in expanding  macros  (see  USE  OF  DEFINE,  13-0)  is
02400	              doubled.   Use this switch if the compiler indicates to
02500	              you that this stack  has  overflowed.   This  shouldn't
02600	              happen  unless  you nest DEFINE calls extremely deeply.
02700	              The compiler is initialized with /6f (i.e.   list  line
02800	              numbers and macro names).
02900	
03000	O     F       O is an octal number which specifies exactly what  kind
03100	              of listing format is generated.  O contains information
03200	              about 5 separate listing features,  each  of  which  is
03300	              assigned a bit in O.
03400	
03500			1	List the program counter (see / L switch below).
03600			2	List with line numbers from the source text.
03700			4	List the macro names before expansion.
03800		       10	Expand macro texts in the listing file.
03900		       20	Surround each listed macro expansion with ⊂ and ⊃ .
04000	
04100	O     L       In compiling  a  SAIL  program,  an  internal  variable
04200	              called  PCNT  (for  program counter) is incremented (by
04300	              one) for each word  of  code  generated.   This  value,
04400	              initially  0,  represents the address of a word of code
04500	              in the running program, relative to the load point  for
04600	              this program.  The current octal value of PCNT plus the
04700	              value of another internal variable called LSTOFFSET, is
04800	              printed  at  the  beginning  of  each  output line in a
04900	              listing file.  For the  first  program  compiled  by  a
05000	              given  SAIL  core  image, LSTOFFSET is initially 0.  If
05100	              the L switch occurs in the command and the value  O  is
     

00100	SAILON NO. 57.2					SAIL   14-13
00200	
00300	              non-negative,   O   replaces   the   current  value  of
00400	              LSTOFFSET.  If O is -1, the current size of DDT is  put
00500	              into  LSTOFFSET.   If O is -2, the current size of RAID
00600	              is used.  In "RPG mode" the  final  value  of  PCNT  is
00700	              added  to  LSTOFFSET  after  each compilation.  Thus by
00800	              deleting all  .REL  files  produced  by  SAIL,  and  by
00900	              compiling  all  SAIL  programs  which  are to be loaded
01000	              together with one RPG  command  which  includes  the  L
01100	              switch,  you can obtain listing files such that each of
01200	              these octal numbers represents the actual starting core
01300	              address  of  the code produced by the line it precedes.
01400	              At the time of this writing, RPG would not accept minus
01500	              signs  in  switches  to  be  sent  to processors.  Keep
01600	              trying.
01700	
01800	D     M       D is a number from 1 to 6.   This  parameter  puts  the
01900	              compiler  in  one  of  several  debugging  modes.  This
02000	              switch is most useful to compiler fixers, but  some  of
02100	              the  modes  are  of  general  interest.   The functions
02200	              represented by each of these  modes  are  described  in
02300	              Debugging modes, 14-14 below.
02400	
02500	      P       Each occurrence of this switch doubles the size of  the
02600	              system  push  down  list.   It  has never been known to
02700	              overflow.
02800	
02900	      Q       Each occurrence doubles the size  of  the  String  push
03000	              down  list.   No  trouble  has  been  encountered here,
03100	              either.
03200	
03300	      R       Each occurrence doubles  the  size  of  the  compiler's
03400	              parsing   and  semantic  stacks.   A  long  conditional
03500	              statement of the form (IF ...  THEN ...   ELSE  IF  ...
03600	              THEN  ...  ELSE IF ...  ) has been known to cause these
03700	              stacks to overflow their normally allocated sizes.
03800	
03900	D     S       The size of String space is Set  to  D  words.   String
04000	              space usage is a function of the number of identifiers,
04100	              especially macros, declared by the user.  In  the  rare
04200	              case  of  String space exhaustion, 5000 is a good first
04300	              number to try.
     

00100	SAILON NO. 57.2					SAIL   14-14
00200	
00300	   
00400	   
00500	Debugging modes
00600	   
00700	   
00800	14-14.    Certain versions of the  SAIL  compiler  have  a  debugging
00900	facility  built  into the inner loop of the parser.  It is willing to
01000	display information about the current state  of  the  compilation  at
01100	strategic  times.   This  routine  can be in one of several modes.  A
01200	debugging mode is initially specified using the  M  switch  described
01300	above.   It can be changed by the user as the compilation progresses.
01400	The modes and their functions are as follows:
01500	
01600	  1)   Just  before  each  code-generator  is  called,  its  name  is
01700	      displayed  on  the  TTY  along with the top few elements of the
01800	      parse and semantic stacks.  If the TTY is a DPY, one also  gets
01900	      the  current input line with an arrow underneath indicating the
02000	      next element to be scanned.  If you do not know  what  to  look
02100	      for  in  the  stack,  don't  use this mode.  Compilation may be
02200	      continued by typing the character "P".
02300	
02400	  2)  No information is displayed in this mode.  However line  breaks
02500	      and asynchronous breaks (see below) can still occur.
02600	
02700	  3)  Just before each parse production  is  compared  to  the  parse
02800	      stack,  the  name  of  the production and the other information
02900	      mentioned  above  is  presented.   Proceed   by   typing   "P".
03000	      Compilation takes forever in this mode.
03100	
03200	  4)  This mode does not cancel any of modes 1, 2,or 3.  However,  it
03300	      puts  the  debugging  routines  in a mode wherein they will not
03400	      wait for a user go-ahead before proceeding  from  the  displays
03500	      described  for  these  modes.  Line and asynchronous breaks are
03600	      still enabled in this mode, and may be used to  regain  control
03700	      of things.
03800	
03900	  5)  This mode has no very useful application if the TTY is really a
04000	      TTY.   However  if it is secretly a DPY, the current input line
04100	      is continuously presented  along  with  an  arrow  showing  the
04200	      compiler's  progress through it.  No user go-ahead is necessary
04300	      after each presentation.  All other modes are cancelled.   Line
04400	      and asynchronous breaks are enabled.
04500	
04600	  6)  This is the default mode.  No information  is  displayed.   The
04700	      debugging routines are completely detached from the compilation
04800	      loop.  Line and asynchronous breaks are disabled.  The only way
04900	      to get any of the information described above is to start over.
     

00100	SAILON NO. 57.2					SAIL   14-15
00200	
00300	   
00400	   
00500	14-15.    If  you have the compiler in a position where it is willing
00600	to listen to a "P" to continue, you may also type some other  things.
00700	The  most interesting one is the "L" command.  Typing "L" followed by
00800	a 5 character  line  number,  a  "/",  and  a  decimal  page  number,
00900	terminated  with  a  carriage return, causes the compiler to remember
01000	this page and line number, and to stop with a Line Break message  and
01100	the  information  described  above  just after the specified line has
01200	been read.  At this point you may change modes (see below) or not, as
01300	you prefer, and type "P" to continue.  This command is really not too
01400	useful unless you are a compiler fixer.
01500	   
01600	   
01700	14-16.     To change  modes  while  compiling,  type  any  number  of
01800	parameter-M  pairs  to the debugging interpreter before typing "P" to
01900	go on.
02000	   
02100	   
02200	14-17.     To get the compiler's attention when it  is  operating  in
02300	one  of  the  modes  2, 4, or 5, simply type a carriage return.  Very
02400	shortly the compiler will display an Asynchronous Break message,  the
02500	print  line, and some stack elements.  Then you may change modes, set
02600	a line break, or simply proceed.  This  is  often  useful  simply  to
02700	convince  yourself  that  your program is still being compiled if you
02800	are running in mode 2.  If you are operating in mode 6, the  compiler
02900	will  not  listen  to your plea.  Start the compiler in mode 2 if you
03000	want  this  feature,  but  be  warned  that  things  will  slow  down
03100	considerably (10%?).
03200	   
03300	   
03400	14-18.    Here  is  an  example  of a compile string which a user who
03500	just has to try every bell and whistle available to him might type to
03600	compile a file named NULL:
03700	
03800	
03900	COMPILE /LIST /SAIL NULL(RR-2L1M4M5000S) 
04000	
04100	The   switch  information  contained  in  parentheses  will  be  sent
04200	unchanged to SAIL.  Note the  convention  which  allows  one  set  of
04300	parentheses enclosing a myriad of switches to replace a "/" character
04400	inserted before each one.  This string tells the compiler to  compile
04500	NULL  using  parse  and  semantic stacks four times larger than usual
04600	(RR).  A listing file is to be made which assumes that RAID  will  be
04700	loaded  and  NULL  will  be  loaded right after RAID (-2L).  The user
04800	wants to see  the  stack  and  input  line  just  before  every  code
04900	generating  routine is called (1M), but he does not want the compiler
05000	to stop after each display (4M).  His program is big enough  to  need
05100	5000 words of String space (5000S).
     

00100	SAILON NO. 57.2					SAIL   14-18
00200	
00300	   
00400	   
00500	ERROR MESSAGES
00600	   
00700	   
00800	14-19.    If  the  compiler  detects a syntax or semantic error while
00900	compiling a program it will  provide  the  user  with  the  following
01000	information:
01100	
01200	  1)  The error message.  These are English phrases  or  sentences
01300	      which  attempt  to  diagnose  the  problem.  If a message is
01400	      vague it is because no specific test for the error has  been
01500	      made  and  a  catchall  routine detected it.  If the message
01600	      begins with the word "DRYROT" it means that there is  a  bug
01700	      in  the  compiler which some strangeness in your program was
01800	      able to tickle.  See a system programmer about this.
01900	
02000	  2)  The current input line.  Page and line  number,  along  with
02100	      the  text  of  the  line  being  scanned, are typed.  If the
02200	      console device is a TTY, a line feed will occur at the point
02300	      in the line just following the last program element scanned.
02400	      If the device is a DPY, the line will be  displayed  with  a
02500	      vertical  arrow  below  the scan position.  The absence of a
02600	      position indicator means that a macro (DEFINE) body is being
02700	      expanded.
02800	
02900	  3)  "CALLED FROM xxxxx".  This is a message of value to compiler
03000	      debuggers only.
03100	
03200	  4)  A question mark or arrow (→ or ↑).
     

00100	SAILON NO. 57.2					SAIL   14-20
00200	
00300	   
00400	   
00500	14-20.    Respond to the prompt in any of the following ways:
00600	
00700	  CR  Try to continue compilation.  A message will be printed  and
00800	      the  sequence  reentered if recovery is impossible (if a "?"
00900	      was typed instead of an arrow).
01000	
01100	  LF  Continue and don't stop from now on.  The program  will  not
01200	      stop  if  it  can  help  it.   Messages  will  fly by (at an
01300	      unreadable rate on DPYs) until the compilation  is  complete
01400	      or  an  error occurs from which no recovery is possible.  In
01500	      the latter case the question sequence is reentered.
01600	
01700	  S   Restart.  Sometimes useful if you are debugging the compiler
01800	      (or  if  you were compiling the wrong file).  The program is
01900	      restarted, accepting compilation commands from the TTY.
02000	
02100	  X   Exit.  All files are closed in  their  current  state.   The
02200	      program exits to the system.
02300	
02400	  L   Look at stack.  This enters a part of the debugging  routine
02500	      (see  Debugging  modes, 14-14 above) to allow examination of
02600	      the parse and semantic stacks.  The compiler will  lead  you
02700	      by the hand through these procedures.
02800	
02900	  E   Edit.  This command must be followed by a  carriage  return,
03000	      or a space, a filename (in standard format, assumes DSK) and
03100	      a carriage return.  If the  filename  is  missing,  the  SOS
03200	      editor  (see  [Savitzky])  is started, given instructions to
03300	      edit the current source file and to move the editing pointer
03400	      to  the  current  page  and  line number.  If a file name is
03500	      present, that file is  edited  starting  at  the  beginning.
03600	      This  feature  is available outside Stanford only if the SOS
03700	      editor is available, and is modified to read a standard  CCL
03800	      file for its input.
03900	
04000	  D   Enter DDT or RAID if one is  loaded.   Otherwise,  type  "NO
04100	      DDT" and re-question.
04200	   
04300	   
04400	14-21.    Any  other  character will cause the error routines to spew
04500	forth a summary of this table and re-enter the question sequence.
     

00100	SAILON NO. 57.2					SAIL   14-22
00200	
00300	   
00400	   
00500	STORAGE ALLOCATION
00600	   
00700	   
00800	14-22.    The compiler dynamically allocates working storage for  its
00900	push down lists, symbol tables, string spaces, etc.  It normally runs
01000	with a  standard  allocation  adequate  for  most  programs.   Switch
01100	settings  given  above  may  be used to change these allocations.  If
01200	desired, these allocations may also be changed by typing ↑C, followed
01300	by REE (reenter).  The compiler will ask you if you want to allocate.
01400	Type Y to allocate, N to use the standard allocation, and  any  other
01500	character  to  use  the  standard allocations and print out what they
01600	are.  All entries will  be  prompted.   Numbers  should  be  decimal.
01700	Typing  alt-mode  instead  of CR will cause standard allocation to be
01800	used for  the  remaining  values.   The  compiler  will  then  start,
01900	awaiting command input from the teletype.
02000	   
02100	   
02200	14-23.    For  Stanford  "Global  Model"  users, the REE command will
02300	also  delete  any  REQUIREd  or   previously   typed   segment   name
02400	information.   The  initialization  sequence  will  then  ask for new
02500	names.
     

00100	SAILON NO. 57.2					SAIL   15-1
00200	
00300	                              SECTION 15
00400	                                    
00500	                          PROGRAM OPERATION
00600	                                    
00700	   
00800	   
00900	LOADING AND STARTING SAIL PROGRAMS
01000	   
01100	Loading
01200	   
01300	   
01400	15-1.    Load the main program,  any  separately  compiled  procedure
01500	files  (see  Separately  Compiled  Procedures,  16-7),  any  assembly
01600	language (see PROCEDURE IMPLEMENTATION, 17-48) or Fortran procedures,
01700	and  DDT  or  RAID  if desired.  This is all automatic if you use the
01800	LOAD or DEBUG or EXECUTE system commands (see [Moorer]).  Any of  the
01900	SAIL  execution  time  routines  requested  by  your  program will be
02000	searched out and loaded automatically from  SYS:LIBSAI.REL.   If  the
02100	shared  segment  (SYS:SAISEG, etc.) is available and desired, type /Y
02200	as as your very first LOADER command (before /D even).  This is  done
02300	automatically by RPG at Stanford.
02400	   
02500	   
02600	Starting the Program -- Normal Operation
02700	   
02800	   
02900	15-2.    For  most  applications,  SAIL programs can by started using
03000	the START, RUN, EXECUTE, or TRY system commands, or by using  the  $G
03100	command  of  DDT (RAID).  The SAIL storage areas will be initialized.
03200	This means that all  knowledge  of  I/O  activity,  associative  data
03300	structures,  strings,  etc.   from  any  previous  activation  of the
03400	program will be lost.  All strings (except constants) will be cleared
03500	to  NULL.   All  compiled-in  arrays which were not PRELOADed will be
03600	cleared to 0, NULL, or PHI, whichever is appropriate.  Then execution
03700	will  begin  with the first statement in the outer block of your main
03800	program.  As each block is entered, its arrays  will  be  cleared  as
03900	they  are  allocated.   Variables  are not cleared.  The program will
04000	exit when it leaves this outer block.
04100	   
04200	   
04300	Starting the Program in "RPG" Mode
04400	   
04500	   
04600	15-3.    SAIL programs may be  started  at  one  of  two  consecutive
04700	locations: at the address contained in the cell JOBSA in the job data
04800	area, or at the address just following that one.  The global variable
04900	RPGSW  is  set to 0 in the former case, -1 in the latter.  Aside from
05000	this, there is no difference between the two methods.  This cell  may
05100	be examined by declaring RPGSW as an EXTERNAL INTEGER.
     

00100	SAILON NO. 57.2					SAIL   15-3
00200	
00300	   
00400	   
00500	Starting the Program with Allocation Modifications
00600	   
00700	   
00800	15-4.    If  the  default  (or REQUIREd) storage allocations for such
00900	things as the push down stacks or string space are insufficient,  the
01000	program  may  be  started  using the REENTER system command.  You may
01100	then answer questions as described in STORAGE ALLOCATION, 14-22.  You
01200	can  find  out  what  the  standard allocations are by typing a space
01300	after the system types ALLOC? at you.  Arrays, Leap  spaces  and  I/O
01400	buffers  are  allocated dynamically, obtaining more storage from the
01500	operating system if necessary.  See Storage Allocation Routines, 17-5
01600	and  following  for  ways  of  cooperating  with SAIL with respect to
01700	storage allocation if you write machine language subroutines.
01800	   
01900	   
02000	ERROR MESSAGES
02100	   
02200	   
02300	15-5.    Error messages have nearly the same format as those from the
02400	compiler (ERROR MESSAGES, 14-19).  They indicate that
02500	
02600	  1)  an array subscript has overflowed;
02700	
02800	  2)  a case index is out of range;
02900	
03000	  3)   a  stack  has  overflowed  while  allocating  space  for  a
03100	      recursive procedure; or
03200	
03300	  4)  one of the execution time routines has detected an error.
03400	   
03500	   
03600	15-6.    The "CALLED FROM" address identifies, in the first 3  cases,
03700	the location in the user program where the error occurred ; the "LAST
03800	SAIL CALL AT" address gives the location of the faulty  call  on  the
03900	SAIL routine for type 4 messages.
04000	   
04100	   
04200	15-7.    All  the  replies  to  error  messages  described  in  ERROR
04300	MESSAGES, 14-19 are valid except the "L" option.  If no file name  is
04400	typed  with  the  "E"  option,  the  editor  re-opens  the  last file
04500	mentioned in the EDIT system command (if the appropriate version  SOS
04600	is available.
04700	   
04800	   
04900	15-8.    The  function USERERR may be used to activate the SAIL error
05000	message mechanism.  See Usererr, 12-124 for details.
     

00100	SAILON NO. 57.2					SAIL   15-8
00200	
00300	   
00400	   
00500	DEBUGGING
00600	   
00700	   
00800	15-9.    The code output for SAIL programs is designed to  be  fairly
00900	easy  to understand when examined using the DDT debugging language or
01000	Stanford's  display  oriented  RAID  program.   A  knowledge  of  the
01100	debugger  you  have  chosen  is  required before this section will be
01200	comprehensible.
01300	   
01400	   
01500	Symbols
01600	   
01700	   
01800	15-10.    Only those symbols which have been declared  INTERNAL  (see
01900	Separately  Compiled  Procedures,  16-7)  and  those  declared in the
02000	currently open "program" are available at a given time.  The name  of
02100	a SAIL program as far as DDT or RAID (henceforth DDRAID) is concerned
02200	is the name of the outer block of that program.  If no name is  given
02300	for this block, the name M.  will be the default.
02400	   
02500	   
02600	15-11.    Only  the first six non-blank characters of a block name or
02700	identifier  will  be  used  in  forming  a  DDRAID  symbol.   If  two
02800	identifiers  in the same block have the same first six characters the
02900	program using them will not get confused, but  the  user  might  when
03000	trying to locate these identifiers.
03100	   
03200	   
03300	15-12.    To  obtain  symbols  for  the execution time routines, load
03400	RUNTIM.REL (available from your friendly local SAIL maintainer)  with
03500	your  other files.  The routines will be loaded from this file, which
03600	includes symbols, instead  of  from  the  LIBSAI  library  or  shared
03700	segment,  which  do not.  Your program will be several thousand words
03800	longer when this file is used.
03900	   
04000	   
04100	Blocks
04200	   
04300	   
04400	15-13.    All  block  names  and  identifiers  used   as   variables,
04500	procedures  or labels in a given (main or separate procedure) program
04600	are available for typeout when that program is "open" (NAME$: has been
04700	typed).   To refer to a symbol, type BLOCK_NAME&SYMBOL/ (; for RAID).
04800	The block name may be omitted if you have  "opened"  the  block  with
04900	BLOCK_NAME$&.   The  symbol  table  is  block-structured  only to the
05000	extent that block names have appeared in  the  source  program.   For
05100	instance, in the program
     

00100	SAILON NO. 57.2					SAIL   15-13
00200	
00300	
00400	
00500	BEGIN "NAME1"
00600	  INTEGER I,J;
00700	  ...
00800	  BEGIN
00900	    INTEGER I,K;
01000	    ...
01100	  END;
01200	  ...
01300	END "NAME1"
01400	
01500	the  symbols  J,  K,  and  both symbols I are considered by DDRAID to
01600	belong in the  same  block.   Therefore  confusion  can  result  with
01700	respect  to  I.   This  approach  was taken to avoid the necessity of
01800	generating meaningless block names for DDRAID when none were given in
01900	the  source  program.   A  compound  statement  will be considered by
02000	DDRAID to be a block if it has a name.
02100	   
02200	   
02300	Sail-Generated Symbols
02400	   
02500	   
02600	15-14.    Some extra symbols are generated by SAIL and will  show  up
02700	when you are using DDRAID.  They are:
02800	
02900	ACS     The accumulators P (system push  down  list  pointer),  SP
03000	        (string  push  down  pointer),  and  TEMP  (commonly  used
03100	        temporary) are given  symbolic  names.   Currently  P='17,
03200	        SP='16, TEMP='14.
03300	
03400	OPS     The op codes for the UUOs ERR., ERROR., FIX, FLOAT, PDLOV,
03500	        and  ARERR  (subscript  overflow UUO) are included to make
03600	        these easy to detect in the code.
03700	
03800	ARRAYS  For each array  declared  in  the  outer  block  (built-in
03900	        arrays), the fixed address of its first element is given a
04000	        symbolic  name.   This  name  is  constructed   from   the
04100	        characters  of the array name (up to the first 5) followed
04200	        by a period.  For instance, the first element of array CHT
04300	        is  CHT.;  the first element of PDQARR is PDQAR.; The last
04400	        semicolon was really a period.  This dotted symbol  points
04500	        to  the  second  word  of  the first descriptor for String
04600	        Arrays (see STRINGS, 17-15, ARRAY IMPLEMENTATION, 17-35).
     

00100	SAILON NO. 57.2					SAIL   15-14
00200	
00300	
00400	BLOCKS  The first word of the first executable statement of  every
00500	        block or compound statement which has been given a name is
00600	        given a label created in the same way as those for  arrays
00700	        above.   This  label  cannot  be  gone  to  in  the source
00800	        program.  It causes no program inefficiency.   This  label
00900	        points  at  the first word of the compound tail -- not the
01000	        first word of code generated  for  the  block  (skips  any
01100	        procedure or array declaration code).
01200	
01300	START   The first word of code generated for any given program  is
01400	        given the name "S.".
01500	   
01600	   
01700	Warnings
01800	   
01900	   
02000	Long Names
02100	   
02200	   
02300	15-16.    Since  only  the  first  6  characters of an identifier are
02400	available, it is wise to declare symbols which will  be  examined  by
02500	DDRAID in such a way that these six characters will uniquely identify
02600	them.
     

00100	SAILON NO. 57.2					SAIL   16-1
00200	
00300	                              SECTION 16
00400	                                    
00500	                          PROGRAM STRUCTURE
00600	                                    
00700	   
00800	   
00900	THE SAIL CORE IMAGE (REQUIRED)
01000	   
01100	   
01200	16-1.    The following  things  must  be  present  in  a  core  image
01300	containing SAIL-compiled files:
01400	   
01500	   
01600	Main Program
01700	   
01800	   
01900	16-2.    A SAIL "main program", or an assembly language program which
02000	looks an awful lot like a SAIL main program, must be present  if  any
02100	SAIL-compiled  files  are.   A  SAIL  source  program  which  has  no
02200	entry-specification as its first element satisfies this  requirement.
02300	The  first  statement  executed  after storage allocation is complete
02400	will be its first statement.  There should be no more than  one  main
02500	program per core image.
02600	   
02700	   
02800	16-3.    The salient characteristics of a main program are:
02900	
03000	  1)  Its .REL file has a starting address block (the loader  will
03100	      tell  the  time  sharing system to start the program at this
03200	      address).
03300	
03400	  2)  Its first task is  to  determine  whether  the  program  was
03500	      started  in  RPG  mode.  If so, the global variable RPGSW is
03600	      set to TRUE; otherwise FALSE.
03700	
03800	  3)  Its  next  task  is  to  call  the  storage  allocator  with
03900	      JSR SAILOR.
04000	
04100	  4)  It should then proceed with the main control of the program.
04200	
04300	  4)  It should execute a POPJ 17,0 when it is all done.
04400	
04500	  5)  It may not execute any UUOs  except  SAIL  UUOs  (nor  alter
04600	      permanently  the  UUO  locations  40  and  41) without great
04700	      caution.
     

00100	SAILON NO. 57.2					SAIL   16-4
00200	
00300	   
00400	   
00500	Storage Allocation, Basic Utilities
00600	   
00700	   
00800	16-4.    There is a set of routines which must always  be  loaded  to
00900	establish   the  operating  environment  for  SAIL  programs.   These
01000	routines allocate storage, set up push down pointers, and  initialize
01100	some  of  SAIL's  internal  tables.   Other routines included in this
01200	package are a String  garbage  collector  (see  STRINGS,  17-15)  and
01300	several basic routines which many others call upon.
01400	   
01500	   
01600	16-5.    These  programs will be loaded automatically from LIBSAI.REL
01700	if the JSR SAILOR instruction, where SAILOR is an  external  request,
01800	is  present  in the main program (this is automatic for SAIL-compiled
01900	main programs).  If the shared segment option is available, they  may
02000	also  be  included by mentioning SYS:SAILOW (or /Y) as the very first
02100	thing in your LOADER input string (done automatically at Stanford.
02200	   
02300	   
02400	Other Execution-Time Routines
02500	   
02600	   
02700	16-6.    All I/O, String-handling, etc.  is done  by  routines  which
02800	understand  about  SAIL.   Programs  requiring  these services should
02900	probably  use  these  routines.   SAIL-compiled  files  automatically
03000	request these blessed routines from LIBSAI.REL, or link to the second
03100	segment versions via RPG at Stanford.
03200	   
03300	   
03400	OPTIONAL ADDITIONS
03500	   
03600	Separately Compiled Procedures
03700	   
03800	   
03900	16-7.    When a program becomes extremely large it becomes useful  to
04000	break  the  program  up  into  several  files  which  can be compiled
04100	separately.  This can be done in SAIL by preparing one file as a main
04200	program,  and  one  or  more  other  files  as programs each of which
04300	contains one or more procedures to be called  by  the  main  program.
04400	Such a file must have the following characteristics:
     

00100	SAILON NO. 57.2					SAIL   16-7
00200	
00300	
00400	  1)  An entry specification (see Entry Specifications, 2-1)  must
00500	      be  the  first item in the program (preceding even the BEGIN
00600	      for its outer block).  The list of identifiers will be  used
00700	      to  form  an Entry Block for the loader.  Therefore the file
00800	      may be placed in a user library if desired.  The  format  of
00900	      libraries  is  described  in  [Weiher].   The  identifier(s)
01000	      appearing in the entry list may be  any  valid  identifiers,
01100	      but  usually  they  will  be  the  names  of  the procedures
01200	      contained in the file.  No starting address will  be  issued
01300	      for   a  program  containing  an  Entry  Specification.   No
01400	      checking is done to see if entry identifiers are ever really
01500	      declared in the body of the program.
01600	
01700	  2)  Since no starting address is present for this file, entry to
01800	      code within it may only be to the  procedures  it  contains;
01900	      the  statements  in  the  outer  block, if any, can never be
02000	      executed.  All procedures to be called from the main program
02100	      (or  procedures  in  other files) must be qualified with the
02200	      INTERNAL  attribute  when  they  are   declared.    External
02300	      procedure  declarations  with headings identical to those of
02400	      the actual declarations must appear in  all  those  programs
02500	      which call these procedures.
02600	
02700	  3)  These internal procedures must be uniquely  identifiable  by
02800	      the  first six characters of their identifiers.  In general,
02900	      any two internal procedure  names  (or  any  other  Internal
03000	      variables  in  the  same core image) with the same first six
03100	      characters will cause incorrect linkages when  the  programs
03200	      are loaded.
03300	
03400	  4)  Any variables (simple or array) which appear  in  the  outer
03500	      block  of  a  Separately  Compiled Procedure program will be
03600	      global to the procedures in this program, but not  available
03700	      to   the   main   program  (unless  they  are  connected  by
03800	      Internal/External declarations --  see  below).   Arithmetic
03900	      arrays  in  these  outer blocks will always be zero when the
04000	      program is first loaded, but will never be cleared as others
04100	      are  (see Starting the Program -- Normal Operation, 15-2) --
04200	      String arrays are always cleared.
04300	
04400	  5)  Any variable, procedure or label may contain  the  attribute
04500	      INTERNAL or EXTERNAL in its declaration (ITEMS may not).
     

00100	SAILON NO. 57.2					SAIL   16-8
00200	
00300	   
00400	   
00500	16-8.    The   INTERNAL   attribute   does  not  affect  the  storage
00600	assignment of the entity it represents, nor does it have  any  effect
00700	on the behavior of the entity (or the scope of its identifier) in the
00800	file wherein it appears.  However, its address  and  (the  first  six
00900	characters  of)  its  name  are  made  available  to  the  loader for
01000	satisfying External requests.
01100	   
01200	   
01300	16-9.    No space is ever  allocated  for  an  External  declaration.
01400	Instead,  a list of references to each External identifier is made by
01500	the compiler.  This list is passed to the loader along with the first
01600	six  characters  of  the  identifier  name.   When  an  Internal name
01700	matching it is found during loading, its associated address is placed
01800	in  each  of  the  instructions  mentioned  on  the list.  No program
01900	inefficiency at all results from  External/Internal  linkages  (belay
02000	that   --   references   to   External   arrays  are  sometimes  more
02100	inefficient).
02200	   
02300	   
02400	16-10.    The entity finally represented by an External identifier is
02500	only  accessible  within  the  scope  of  the  External  declaration.
02600	Transfers to external labels are always allowed, but if  things  work
02700	correctly when this is done it is only by sheer luck that they do.
02800	   
02900	   
03000	Fortran Procedures
03100	   
03200	   
03300	16-11.    For  a program written in DEC FORTRAN IV to run in the SAIL
03400	environment, the following restrictions must be observed:
03500	
03600	  1)  It must be a SUBROUTINE or FUNCTION, not a main program.
03700	
03800	  2)  It  must  not  execute  any  FORTRAN  I/O  calls.   The  UUO
03900	      structures of the two languages are not compatible.
04000	
04100	  3)  It must be declared as  a  Fortran  Procedure  (see  Fortran
04200	      Procedures, 6-12) in the SAIL program which calls it.
04300	   
04400	The  type  bits  required  in  the  argument  addresses  for  Fortran
04500	arguments are passed correctly to these routines.
04600	   
04700	The SAIL compiler will not produce a  procedure  to  be  called  from
04800	FORTRAN.
     

00100	SAILON NO. 57.2					SAIL   16-12
00200	
00300	   
00400	   
00500	Assembly Language Procedures
00600	   
00700	   
00800	16-12.    The   implementation   section   contains   the   following
00900	paragraphs to aid  in  writing  assembly  language  procedures:  User
01000	Table,  17-1,  STRINGS,  17-15,  ARRAY IMPLEMENTATION, 17-35, Storage
01100	Allocation Routines, 17-5, and PROCEDURE IMPLEMENTATION,  17-48.   In
01200	addition, the following rules should be observed:
01300	
01400	  1)  The ENTRY, INTERNAL, and EXTERNAL pseudo-ops should be  used
01500	      to   obtain   linkages  for  procedure  names  and  "global"
01600	      identifiers (remember that only six characters are used  for
01700	      these linkage names.
01800	
01900	  2)  Accumulators P  (currently  '17)  and  SP  ('16)  should  be
02000	      preserved over function calls.  P may be used as a push-down
02100	      pointer for arithmetic values and return addresses.   SP  is
02200	      the  string  stack  pointer.  String results are returned on
02300	      this stack.  Arithmetic results are returned in  AC  1  (see
02400	      PROCEDURE IMPLEMENTATION, 17-48).
02500	
02600	  3)  The UUO locations 40 and 41 should be preserved.
02700	
02800	  4)  JOBFF must be set by the  user  to  some  free  buffer  area
02900	      before   OUTBUF  or  INBUF  UUOs  are  executed.   JOBFF  is
03000	      periodically set by SAIL routines to an invalid address.
03100	
03200	  5)  The CORE UUO may be used to increase memory size, but  never
03300	      to  decrease  it.   Never attempt to use directly any of the
03400	      memory space currently assigned  to  the  job  (except  that
03500	      explicitly  provided  in  the  routine).  Release all memory
03600	      obtained in this way before returning to SAIL routines.  See
03700	      Storage   Allocation  Routines,  17-5  for  instructions  on
03800	      obtaining core from  the  SAIL  memory  allocators  (a  much
03900	      safer, and sometimes faster way).
04000	   
04100	   
04200	Others
04300	   
04400	   
04500	16-13.    There  are  no  other  known  processors which will produce
04600	SAIL-compatible programs.  In particular, the LISP 1.6 system, by its
04700	very   nature,   contains  storage  allocation  conflicts  which  are
04800	difficult to resolve.  If a great need for this kind of compatibility
04900	develops it can be provided.
     

00100	SAILON NO. 57.2					SAIL   17-1
00200	
00300	                              SECTION 17
00400	                                    
00500	                      IMPLEMENTATION INFORMATION
00600	                                    
00700	   
00800	   
00900	STORAGE LAYOUT
01000	   
01100	User Table
01200	   
01300	   
01400	17-1.    All  working  storage areas for a SAIL-generated program and
01500	its execution-time routines are dynamically allocated  --  some  just
01600	once when the program is first started, some as more space is needed.
01700	   
01800	   
01900	17-2.    The  first  area  allocated  is a several hundred word table
02000	which contains information about  the  remaining  storage  areas  and
02100	global  variables for the execution-time routines.  A single internal
02200	variable, GOGTAB, will always contain a pointer to this  table.   The
02300	execution-time  routines  make  all  accesses to storage through this
02400	table or through user-supplied addresses.  They  would  therefore  be
02500	totally  re-entrant  if the GOGTAB variable were allowed to vary over
02600	several users.
02700	   
02800	   
02900	17-3.    A FAIL source file containing symbolic indices for the  user
03000	table,  as  well  as  some  useful  MACROs,  OPDEFs,  and accumulator
03100	definitions is available to provide accessability to this  table  for
03200	assembly  language routines.  This file may be concatenated to a FAIL
03300	program before assembly.  Users can read and modify these entries  in
03400	SAIL via the procedure Usercon, 12-120.
03500	   
03600	   
03700	17-4.    Most  execution-time  routines load the address contained in
03800	GOGTAB into the accumulator USER (currently '15) in  order  to  index
03900	the  user  table.   Thus in what follows, symbolic index XX into this
04000	table will be listed as XX(USER).
04100	   
04200	   
04300	Storage Allocation Routines
04400	   
04500	   
04600	17-5.    SAIL makes all requests for  storage  through  the  routines
04700	CORGET,  CORREL,  CORINC,  CORBIG,  and  CANINC.   These routines are
04800	described in the following paragraphs.  The AC's  THIS  and  SIZ  are
04900	currently set to 2 and 3, respectively.  All core routines are called
05000	with PUSHJ 17,routine.
     

00100	SAILON NO. 57.2					SAIL   17-5
00200	
00300	   
00400	   
00500	Corget
00600	   
00700	   
00800	17-6.    Corget is called with the desired size of a block of storage
00900	in  register  SIZ.   It returns the address of the new block in THIS.
01000	No other accumulators are altered.  Normally the  function  skips  on
01100	return.   It does not skip if insufficient core is available to grant
01200	the request.  The address returned is that of  the  first  free  data
01300	word (DATA below).
01400	   
01500	   
01600	17-7.    A SAIL core block has the following form:
01700	
01800	
01900	HEAD:	→LAST,,→NEXT	;when not in use (free list links)
02000		SIZE		;END-HEAD+1, negated when block is in use
02100	DATA:	BLOCK	SIZE-3	;available to user -- sometimes a few more
02200				;   words than requested will be contained
02300				;   in the block
02400	END:	USEBIT,,→HEAD	;USEBIT is 400000 if block is in use; else 0
02500	
02600	The  first  time  CORGET is called, GOGTAB is 0.  CORGET notices this
02700	and performs the following special actions:
02800	
02900	  1)  Prepares to allocate  storage  just  past  the  program  and
03000	      symbols (left half of JOBSA contains the relevant address).
03100	
03200	  2)  Allocates the user table; puts pointer in GOGTAB.
03300	
03400	  3)  Forms remaining free storage from the end of the user  table
03500	      to  contents  (JOBREL)  [C(JOBREL)]  into a single free SAIL
03600	      block.  Puts →HEAD in LO(USER), FRE(USER).  Puts C(JOBREL)+1
03700	      in TOP(USER).
03800	
03900	  4)  Performs the requested CORGET operation.
04000	   
04100	   
04200	17-8.    FRE(USER) is the header  of  a  linked  free  storage  list,
04300	Blocks  are  obtained from this list and the list is updated.  CORREL
04400	releases blocks onto this list.  If  no  currently  free  block  will
04500	satisfy  a  CORGET request, the CORE UUO is executed to get more from
04600	the time sharing system.
     

00100	SAILON NO. 57.2					SAIL   17-9
00200	
00300	   
00400	   
00500	17-9.    Users are free to use the CORGET function if  they  will  be
00600	careful  of  the  two  header  words  and  the  single  trailer  word
00700	associated with each block.  Release these blocks as soon as possible
00800	to prevent undue checker-boarding of free storage.
00900	   
01000	   
01100	Correl
01200	   
01300	   
01400	17-10.    Correl   is   called  with  the  address  obtained  in  the
01500	corresponding Corget call (the DATA address) in register  THIS.   The
01600	block  is  returned  to  the free storage list.  If either of the two
01700	neighboring blocks is already free,  the  adjacent  free  blocks  are
01800	merged  with  the  one  being  released to form a bigger one.  If the
01900	block being released is uppermost in core, and if  it  occupies  more
02000	than  about  2K, the core size of the program is contracted using the
02100	CORE UUO.  About 2K of free storage is left in this case.  No ACs are
02200	altered by CORREL.
02300	   
02400	   
02500	Corinc
02600	   
02700	   
02800	17-11.    Corinc  is  called with the DATA address of a SAIL block in
02900	THIS and a desired increment in  SIZ.   If  there  is  a  free  block
03000	directly above the THIS block with at least SIZ free words, or if the
03100	THIS block occupies the highest addresses of any block  in  use,  the
03200	request  is  granted,  the  block  is  extended  by SIZ words and the
03300	function executes a skip-return.  Otherwise no  skip  occurs  and  no
03400	action is taken.  No ACs will be altered.
03500	   
03600	   
03700	Caninc
03800	   
03900	   
04000	17-12.    Caninc  performs  the  same tests as Corinc and skips under
04100	the same conditions.  It also uses the same calling sequence.  If  it
04200	does  not  skip,  it  returns  with SIZ altered to show the number of
04300	words by which the DATA block can  be  increased.   It  is  0  if  no
04400	increase  is  possible.   This  function  never  affects current core
04500	allocation.
     

00100	SAILON NO. 57.2					SAIL   17-13
00200	
00300	   
00400	   
00500	Corbig
00600	   
00700	   
00800	17-13.    Corbig returns the size of the largest available free block
00900	in SIZ.
01000	   
01100	   
01200	17-14.    These  functions  are  not available to SAIL programs since
01300	core can be obtained by array declarations (which in turn  use  these
01400	functions).
01500	   
01600	   
01700	STRINGS
01800	   
01900	String Descriptors
02000	   
02100	   
02200	17-15.    A  SAIL  String  has two distinct parts: the descriptor and
02300	the text.  The descriptor is unique and has the following format:
02400	
02500	
02600	WORD1:	STRINGNO,,LENGTH
02700	WORD2:	BYTP
02800	
02900	
03000	  1)  STRINGNO.  This entry is 0 if the String is a constant  (the
03100	      descriptor  will  not be altered, and the String text is not
03200	      in  String  space,  is  therefore  not  subject  to  garbage
03300	      collection).   Every  time  a  String  is  created  via  the
03400	      concatenation   operator,   or   Input   function,   or   an
03500	      Integer-String  type conversion, it receives a new STRINGNO.
03600	      Each new String receives a number one greater than the last,
03700	      starting  at 1 when the program is initialized.  All strings
03800	      formed as substrings of  a  given  String  have  the  String
03900	      number of the original (major) string.  These numbers aid in
04000	      increasing String garbage collection efficiency.
04100	
04200	  2)  LENGTH.  This number is zero for any null String;  otherwise
04300	      it is the number of text characters.
04400	
04500	  3)  BYTP.  If count is 0, this byte pointer is never checked (it
04600	      need  not  even be a valid byte pointer.  Otherwise, an ILDB
04700	      machine instruction pointed at the BYTP word  will  retrieve
04800	      the  first  text  character  of  the String.  The text for a
04900	      String may begin at any point in a word.  The characters are
05000	      stored as LENGTH contiguous characters.
     

00100	SAILON NO. 57.2					SAIL   17-16
00200	
00300	   
00400	   
00500	17-16.    A SAIL String variable contains the two word descriptor for
00600	that variable.  The identifier naming it  points  to  WORD1  of  that
00700	descriptor.   If a String is declared INTERNAL, a symbol is formed to
00800	reference WORD2 by taking all characters from the original  name  (up
00900	to  5)  and  concatenating  a  "."  (OUTSTRING's second word would be
01000	labeled OUTST.).
01100	   
01200	   
01300	17-17.    When a String is passed by reference to  a  procedure,  the
01400	address   of   WORD2   is   placed  in  the  P-stack  (see  PROCEDURE
01500	IMPLEMENTATION, 17-48).  For VALUE Strings both descriptor words  are
01600	pushed onto the SP stack.
01700	   
01800	   
01900	17-18.    A  String  array  is  a block of 2-word String descriptors.
02000	The array descriptor (see ARRAY IMPLEMENTATION, 17-35) points at  the
02100	second word of the first descriptor in the array.
02200	   
02300	   
02400	17-19.    Information  is  generated  by  the  compiler  to allow the
02500	locations of all non-constant strings to be  found  for  purposes  of
02600	garbage-collection  and initialization (see PROCEDURE IMPLEMENTATION,
02700	17-48).  All String variables and arrays are cleared to NULL whenever
02800	a SAIL program is started.
02900	   
03000	   
03100	String Operations
03200	   
03300	   
03400	17-20.    The  five  basic String operations are concatenation (CAT),
03500	substrings (SUBSTR),  String-integer  (done  inline),  Integer-string
03600	(PUTCH),  and one-character truncation (LOP, compiled inline).  Other
03700	functions producing  or  operating  upon  strings  are  described  in
03800	Execution Routines, 12-1.
     

00100	SAILON NO. 57.2					SAIL   17-21
00200	
00300	   
00400	   
00500	Cat
00600	   
00700	   
00800	17-21.    CAT forms a new String from two other strings (constants or
00900	otherwise).  The calling sequence is:
01000	
01100	
01200		PUSH	SP,WORD11	;WORD1, FIRST ARGUMENT
01300		PUSH	SP,WORD12	;WORD2, FIRST ARGUMENT
01400		PUSH	SP,WORD21	;ETC.
01500		PUSH	SP,WORD22
01600		PUSHJ	P,CAT
01700	
01800	The result is found as a new two-word descriptor on  top  of  the  SP
01900	(currently AC '16) stack.  If either argument is the null String, the
02000	result is the other argument.  If the  first  argument  occupies  the
02100	space  directly  preceding  the first free character in String space,
02200	only the second argument is copied.  Otherwise,  both  arguments  are
02300	copied  (in  order) into free space to form the result.  A new String
02400	number is created for this result.  The LENGTH field is  the  sum  of
02500	the LENGTHs of the two arguments.
02600	   
02700	   
02800	Substr
02900	   
03000	   
03100	17-22.    SUBSTR  returns  a  descriptor  representing  a part of its
03200	input argument.  SUBSTR is really two routines, called as follows:
03300	
03400	
03500			 PUSH  SP,WORD1
03600			 PUSH  SP,WORD2
03700	
03800		   SUBST	    SUBSR
03900		PUSH P,LASDX	 PUSH   P,NUMCHR
04000		PUSH P,FIRSDX    PUSH   P,FIRSDX
04100	
04200			 PUSHJ P,SUBS{T/R}
04300	
04400	LASDX is the number of the last character to  be  included  (starting
04500	with 1).  FIRSDX is the number of the first character to be included.
04600	NUMCHR is the number of characters to be included.
     

00100	SAILON NO. 57.2					SAIL   17-23
00200	
00300	   
00400	   
00500	17-23.    The result is always a two-word descriptor in the SP  stack
00600	describing the substring.
00700	   
00800	SUBST is used for the construct ST[X for Y].
00900	SUBSR is used for ST[X to Y].
01000	   
01100	   
01200	17-24.    An error code is returned if the request can not be totally
01300	satisfied (see Substrings, 9-42).
01400	   
01500	   
01600	17-25.    The String number of the output is the same as  the  String
01700	number of the input.
01800	   
01900	   
02000	String to Integer
02100	   
02200	   
02300	17-26.    This   returns   the   first   string   character  (or  0),
02400	right-justified, in an accumulator.  It  is  invoked  when  something
02500	like I←STR is executed (see String-Arithmetic Conversions, 9-27).  It
02600	is compiled as
02700	
02800	
02900		HRRZ 	AC,WORD1
03000		JUMPE	AC,.+3
03100		MOVE	AC,WORD2
03200		ILDB	AC,AC
03300	
03400	   
03500	   
03600	Putch
03700	   
03800	   
03900	17-27.    Call with
04000	
04100	
04200		PUSH	P,VALUE
04300		PUSHJ	P,PUTCH
04400	
04500	The result is a String descriptor with count of 1 on top  of  the  SP
04600	stack.   The  P  stack is adjusted to remove the parameter and return
04700	address.  The String number is new.  The low order 7  bits  of  VALUE
04800	form the single character in the string.
     

00100	SAILON NO. 57.2					SAIL   17-28
00200	
00300	   
00400	   
00500	Lop Details
00600	   
00700	   
00800	17-28.    LOP(ST) is compiled inline as:
00900	
01000	
01100		HRRZ	AC,WORD1
01200		JUMPE	AC,.+3
01300		ILDB	AC,WORD2	;return 1st char, update bp
01400		SOS	WORD1		;decrement character count
01500	
01600	   
01700	   
01800	String Space
01900	   
02000	   
02100	17-29.    The  normal  or  user-specified  (see  STORAGE  ALLOCATION,
02200	14-22) number of words required for  strings  is  used  to  obtain  a
02300	single  SAIL  block  (see Storage Allocation Routines, 17-5) when the
02400	program is started.  The limits of this area are placed  in  ST(USER)
02500	and STTOP(USER).  Other parameters are set up as described below.
02600	   
02700	   
02800	17-30.    String text characters are placed contiguously in thes area
02900	as strings are created.   When  not  enough  storage  remains  for  a
03000	contemplated  String,  the  garbage  collector  (see  String  Garbage
03100	Collection, 17-32) is  called  to  obtain  more  (by  compacting  the
03200	current space, if possible).  If this fails, the program will restart
03300	and request more reasonable allocation.
     

00100	SAILON NO. 57.2					SAIL   17-31
00200	
00300	   
00400	   
00500	Parameters Used by String Operations
00600	   
00700	   
00800	17-31.    
00900	
01000	ST(USER)         Bottom (low address) of String space
01100	
01200	STTOP(USER)      (Top+1) of String space
01300	
01400	TOPBYTE(USER)    Byte pointer such that  IDPB  TOPBYTE(USER)  will
01500	                 store into next character
01600	
01700	REMCHR(USER)     Negated number of free characters remaining
01800	
01900	TOPSTR(USER)     WORD1 for last created  String  (doesn't  include
02000	                 substring  operations).   CAT  uses  this word to
02100	                 decide whether its first  argument  needs  to  be
02200	                 moved (see Cat, 17-21).
02300	   
02400	   
02500	String Garbage Collection
02600	   
02700	   
02800	17-32.    The  String  garbage  collector (STRNGC) is called whenever
02900	the (estimated or actual) size  of  a  soon-to-be-created  String  is
03000	larger  than  -REMCHR(USER).   By  various devious means it finds all
03100	active (non-constant) String descriptors, sorting them  in  ascending
03200	address   sequence  by  using  the  byte  pointers,  associating  all
03300	substrings of a given active String (major String) ...ouch.  Then  it
03400	compacts  String  space  by  moving the text for all major strings to
03500	lower memory locations occupied by text no longer reachable from  any
03600	descriptor.   Finally  it  updates  all  String  descriptors  and the
03700	parameters described above.  If there is still not  enough  room,  it
03800	prints  a  frustrated  message  and  restarts  the  program  with the
03900	allocation sequence normally obtained by typing  the  REEnter  system
04000	command (see STORAGE ALLOCATION, 14-22).
     

00100	SAILON NO. 57.2					SAIL   17-33
00200	
00300	   
00400	   
00500	String-Oriented Machine Language Routines
00600	   
00700	   
00800	17-33.    If  you  must  write  a  routine which operates on strings,
00900	please observe the following conventions:
01000	
01100	  1)    See  PROCEDURE  IMPLEMENTATION,  17-48   for   conventions
01200	       concerning input parameters and value returning.
01300	
01400	  2)   If you merely need to read a String, no particular care  is
01500	       required (don't change the descriptor of a reference String
01600	       parameter by performing careless ILDBs).
     

00100	SAILON NO. 57.2					SAIL   17-34
00200	
00300	   
00400	   
00500	17-34.    If you  need  to  create  a  new  String,  these  are  also
00600	applicable:
00700	
00800	  4)   Estimate the number  of  characters  if  it  is  not  known
00900	       exactly.    This  estimate  must  be  an  upper  bound;  an
01000	       unrealistically  large  estimate  will  cause  the  garbage
01100	       collector  to  work  more  often than necessary.  Place the
01200	       estimate in register A (1).
01300	
01400	  4)     Execute   the   following   code   before    doing    any
01500	       String-munching:
01600	
01700	
01800			MOVE	USER,GOGTAB	;ESTABLISH ADDRESSABILITY
01900			ADDM	A,REMCHR(USER)	;UPDATE REMAINING COUNT
02000			SKIPLE	REMCHR(USER)	;TEST IMPENDING OVERFLOW
02100			PUSHJ	P,STRNGC	;COLLECT, WILL NOT RETURN IF
02200						; NEW REMCHR+C(A)>0.
02300	
02400	
02500	  5)   TOPBYTE(USER) should be your WORD2 result.  Save it now.
02600	
02700	  6)   Do repeated IDPBs to TOPBYTE(USER) to  store  your  string.
02800	       This  keeps  TOPBYTE  accurate.   Count  characters if your
02900	       estimate was only an estimate.
03000	
03100	  7)   Create WORD1 of your result.  The left  half  is  the  left
03200	       half of TOPSTR(USER) incremented by one.  The right half is
03300	       the length of your new string.  This word is not only WORD1
03400	       of your result, but also should be placed in TOPSTR(USER).
03500	
03600	  8)   Subtract (estimate - actual length)  from  REMCHR(USER)  to
03700	       keep  it  honest.  This should make REMCHR if anything more
03800	       negative.
03900	
04000	  9)   Return String results on the top of the  SP  stack.   If  a
04100	       result  is  to  go  in a reference parameter (see PROCEDURE
04200	       IMPLEMENTATION, 17-48) remember that the address  you  have
04300	       is that of the WORD2 (byte pointer) word of the descriptor.
     

00100	SAILON NO. 57.2					SAIL   17-35
00200	
00300	   
00400	   
00500	ARRAY IMPLEMENTATION
00600	   
00700	Form
00800	   
00900	   
01000	17-35.    Let  STRINGAR  be  1  (TRUE)  if the array in question is a
01100	String array, 0 (FALSE) otherwise.  Then a SAIL array of n dimensions
01200	has the following format:
01300	
01400	
01500	HEAD:	→DATAWD		;→ MEANS "POINTS AT"
01600		HEAD-END-1
01700	ARRHED:	BASE_WORD	;SEE BELOW
01800		LOWER_BD(n)
01900		UPPER_BD(n)
02000		MULT(n)
02100		...
02200		LOWER_BD(1)
02300		UPPER_BD(1)
02400		MULT(1)
02500		NUM_DIMS,,TOTAL_SIZE
02600	DATAWD:	BLOCK	TOTAL_SIZE
02700		<sometimes a few extra words>
02800	END:	400000,,→HEAD
02900	
03000	   
03100	   
03200	Explanation
03300	   
03400	   
03500	17-36.    
03600	
03700	HEAD         The first two words of each array, and the  last,  are
03800	             control  words  for  the  Storage Allocation Routines,
03900	             17-5.  These words are always present  for  an  array.
04000	             The array access code does not refer to them.
04100	
04200	ARRHED       Each array is preceded by a  block  of  3*n+2  control
04300	             words.  The BASE_WORD entry is explained later.
04400	
04500	NUM_DIMS     This is the dimensionality of the array.  If STRINGAR,
04600	             this value is negated before storage in the left half.
04700	
04800	TOTAL_SIZE   The total number of  accessible  elements  (double  if
04900	             STRINGAR) in the array.
     

00100	SAILON NO. 57.2					SAIL   17-36
00200	
00300	
00400	BOUNDS       The lower bound and upper bound for each dimension are
00500	             stored  in  this  table,  the  left-hand  index values
00600	             occupying the higher addresses (closest to  the  array
00700	             data).   If  they  are  constants,  the  compiler will
00800	             remember them  too  and  try  for  better  code  (i.e.
00900	             immediate operands).
01000	
01100	MULT         This number, for dimension m, is the  product  of  the
01200	             total  number of elements of dimensions m+1 through n.
01300	             MULT for the last dimension is always 1.
01400	
01500	BASE_WORD    This is
01600	                
01700	             DATAWD - the sum of (STRINGAR+1)*LOWER_BD(m)*MULT(m)
01800	                
01900	             for all m from 1 to n.  The  formula  for  calculating
02000	             the address of A[I,J,K] is:
02100	
02200	
02300		address(A[I,J,K]) = 
02400		    address(DATAWD) + 
02500		      (I-LOWER_BD(1))*MULT(1) + 
02600		      (J-LOWER_BD(2))*MULT(2) + 
02700		      (K-LOWER_BD(3))
02800	
02900	             This expands to
03000	
03100	
03200		address(A[I,J,K]) =
03300		    address(DATAWD) +
03400		     I*MULT(1) + J*MULT(2) + K
03500		       -(LOWER_BD(1)*MULT(1) + LOWER_BD(2)*MULT(2) + LOWER_BD(3)
03600	
03700	             which is
03800	
03900	
04000		    BASE_WORD + I*MULT(1) + J*MULT(2) + K.
04100	
04200	             By  pre-calculating  the  effects of the lower bounds,
04300	             several  instructions  are  saved   for   each   array
04400	             reference.
     

00100	SAILON NO. 57.2					SAIL   17-37
00200	
00300	   
00400	   
00500	Array Allocation
00600	   
00700	Dynamic Arrays
00800	   
00900	   
01000	17-37.    When an array is declared in any block other than the outer
01100	one, the compiler generates code to  call  the  function  ARMAK  with
01200	parameters  describing  the  array.   This  routine calls CORGET (see
01300	Storage Allocation Routines, 17-5) to  obtain  enough  storage,  then
01400	sets  up  the  control table and clears the data area to zeroes.  The
01500	ARRHED address is saved in an array push-down list whose  pointer  is
01600	ARRPDP(USER).  The address of DATAWD+1 is returned for String arrays;
01700	the address of DATAWD is  returned  for  all  others.   The  compiler
01800	generates  code  to  store  this address in the core cell bearing the
01900	name of the array variable.
02000	   
02100	   
02200	17-38.    When  all  declarations  for  a  block   containing   array
02300	declarations have been processed, the compiler issues a call to ARMRK
02400	which marks the array push-down stack (with a  -1,  as  a  matter  of
02500	fact).   On  block exit (or when a GO TO transfers out of the block),
02600	the routine ARREL is called to remove this mark and return all arrays
02700	back to the previous mark to the SAIL free storage list.
02800	   
02900	   
03000	17-39.    The String garbage collector uses the array push-down stack
03100	to find dynamic String arrays which need attention.
03200	   
03300	   
03400	Built-In Arrays
03500	   
03600	   
03700	17-40.    Outer-block arrays  have  constant  bounds.   The  compiler
03800	simply emits a Jrst instruction, then compiles the control table into
03900	the block head of the object program.  It leaves room for the  array,
04000	then  issues  the END word.  The Jrst instruction then finds its home
04100	in some code to clear the array to zeroes.
04200	   
04300	   
04400	17-41.    The core location bearing the name of  the  array  has  the
04500	address  of  DATAWD  (DATAWD+1  if  STRINGAR) compiled into it.  This
04600	address is given the dotted name described in DEBUGGING, 15-9.
     

00100	SAILON NO. 57.2					SAIL   17-42
00200	
00300	   
00400	   
00500	17-42.    For built-in  String  arrays,  a  String  link  block  (see
00600	PROCEDURE  IMPLEMENTATION,  17-48)  is  issued  following  the  space
00700	allocated for the array.  The String garbage  collector  (see  String
00800	Garbage  Collection,  17-32)  gains access to this array through this
00900	static link.
01000	   
01100	   
01200	17-43.    It can be seen from all this that all dynamic and  built-in
01300	arrays  are  cleared  when  the blocks in which they are declared are
01400	entered.  Since the outer block of a  separately  compiled  procedure
01500	file (see Separately Compiled Procedures, 16-7) is never entered, its
01600	built-in arrays, although available for use, are never cleared.   The
01700	loader clears them once as it loads.
01800	   
01900	   
02000	Array Access Code
02100	   
02200	   
02300	17-44.    In  the  worst  case (no fixed bounds, bounds checking, not
02400	built-in) the statement K←A[I,J] will be compiled as:
02500	
02600	
02700		MOVE	1,A		;→FIRST DATA WORD
02800		MOVE	2,I		;FIRST SUBSCRIPT
02900		CAML	2,-4(1)		;IF <LOWER BOUND OR
03000		CAMLE	2,-3(1)		; >UPPER BOUND THEN
03100		ARERR	1,[ASCIZ /A/]	;  ERROR IN INDEX 1
03200		IMUL	2,-2(1)		;I*MULT(1)
03300		MOVE	3,J		;CHECK DIMENSION 2
03400		CAML	3,-7(1)
03500		CAMLE	3,-6(1)
03600		ARERR	2,[ASCIZ /A/]
03700		ADD	3,2		;NO MULT FOR LAST, COLLECT OFFSET
03800		ADD	3,-10(1)	;  + BASE_WORD
03900		MOVE	4,(3)		;DATA FROM A[I,J]
04000		MOVEM	4,K
04100	
     

00100	SAILON NO. 57.2					SAIL   17-45
00200	
00300	   
00400	   
00500	17-45.    If A is, however, declared  in  the  outer  block  as  SAFE
00600	INTEGER ARRAY A[1:10,1:5], the code for A[I,J] is
00700	
00800	
00900		MOVE	1,I
01000		IMULI	1,5		;I*MULT(1)
01100		ADD	1,J		;COLLECT OFFSET
01200		MOVE	2,A.-5(1)	;CONSTANT PART OF ADDRESS COMPILED IN
01300		MOVEM	2,K
01400	
01500	   
01600	   
01700	17-46.    A[I,3] would be compiled as
01800	
01900	
02000		MOVE	1,I
02100		IMULI	1,5
02200		MOVE	2,A.-2(1)
02300		MOVEM	2,K
02400	
02500	and J←A[2,3] would be
02600	
02700		MOVE	3,A.+7
02800		...
02900		MOVEM	3,J
03000	   
03100	   
03200	17-47.    Various  configurations  of array declarations and accesses
03300	result in code which ranges between these degrees of efficiency.
03400	   
03500	   
03600	PROCEDURE IMPLEMENTATION
03700	   
03800	   
03900	17-48.    
04000	   
04100	   
04200	Procedure Body
04300	   
04400	   
04500	17-49.    To describe the main characteristics of SAIL procedures,  a
04600	set  of sample procedures are displayed here along with the code they
04700	produce.  Some of the entries are discussed  in  more  detail  below.
04800	The  notation  [n]  is  placed  in  the comment field of the assembly
04900	instruction to refer to these discussions:
     

00100	SAILON NO. 57.2					SAIL   17-49
00200	
00300	
00400	
00500	INTEGER PROCEDURE P1(INTEGER I,J; STRING A);
00600		P1:	AOS	P1PAC	;[1] INCREMENT PROC ACTIVE COUNTER
00700	
00800	BEGIN
00900	 INTEGER Q; STRING A,B;
01000	 INTEGER ARRAY X[0:5];
01100			PUSH	P,[0]
01200			PUSH	P,[5]
01300			PUSH	P,[1]
01400			PUSHJ	P,ARMAK	;ALLOCATE AND CLEAR
01500			MOVEM	1,X	;STORE POINTER
01600			PUSHJ	P,ARMRK	;END OF ARRAYS FOR BLOCK
01700	
01800	
01900	 <code for procedure>
02000	
02100	 RETURN(Q);
02200			MOVE	1,Q	;[2] RESULT IN 1
02300			PUSHJ	P,ARREL	;[3] RELEASE ARRAYS FOR BLOCK
02400			JRST	P1EXIT	;EXIT PROCEDURE
02500	
02600	 <more code for procedure>
02700	
02800	
02900	END "P1"
03000			PUSHJ	P,ARREL	;IF FALLS THROUGH, RELEASE ARRAYS
03100		P1EXIT:	SOS	P1PAC	;ONE TIME LESS ACTIVE
03200			SUB	SP,[XWD 2,2]	;REMOVE STRING PARAMETER
03300			SUB	P,[XWD 3,3]	;[4] NON-STRINGS, RETURN ADDR
03400			JRST	@3(P)		;RETURN
03500		Q:	0		;ROOM FOR VARIABLE
03600		X:	0		;ARRAY POINTER
03700		TEMP07:	0		;[5] TEMPORARY STORAGE
03800		A:	BLOCK	2	;TWO WORDS FOR EACH STRING
03900		B:	BLOCK	2
04000		P1PAC:	0		;[6] PROCEDURE-ACTIVE COUNT
04100			XWD	2,A	;STRING COUNT,→FIRST
04200		LNKWD:	0		;[7] LINK PASSES THROUGH HERE
04300			LINK	1,LNKWD	;[7] CAUSES LOADER LINKAGE
04400	
04500	
04600	
04700	
04800	PROCEDURE P2(INTEGER I,J; STRING A);
04900	BEGIN
05000	 INTEGER ARRAY X[0:10];
05100	 ...
     

00100	SAILON NO. 57.2					SAIL   17-49
00200	
00300	 BEGIN
00400	  INTEGER ARRAY Y[0:10];
00500	  ...
00600	   RETURN;
00700			PUSHJ	P,ARREL		;RELEASE ARRAYS FOR ALL
00800			PUSHJ	P,ARREL		; BLOCKS IN PROCEDURE
00900			JRST	P2EXIT
01000	
01100	  ...
01200	 END;
01300	END"P2";
01400	
01500	
01600	
01700	STRING PROCEDURE P3(STRING A,B);
01800	BEGIN STRING C;
01900	 ...
02000	 RETURN(C);
02100			SUB	SP,[XWD 4,4]	;REMOVE PARAMS
02200			PUSH	SP,C
02300			PUSH	SP,C+1		;RETURN STRING RESULT
02400			JRST	P3EXIT
02500	
02600	 RETURN(B);
02700			SUB	SP,[XWD 4,4]
02800			PUSH	SP,3(SP)	;FIRST WORD OF B
02900			PUSH	SP,3(SP)	;SECOND WORD OF B
03000			JRST	P3EXIT		;GO RETURN
03100	
03200	 RETURN(C&"STR"); COMMENT ASSUME CAT ALREADY DONE;
03300			SUB	SP,[XWD 6,6]	;REMOVE PARAMS, TEMP RESLT
03400			PUSH	SP,5(SP)	;TEMP RESLT
03500			PUSH	SP,5(SP)	;2D WORD
03600			JRST	P3EXIT
03700	
03800	 ...
03900	END "P3";
04000		P3EXIT:	SOS	P3PAC
04100			SUB	SP,[XWD 4,4] ;NOT THIS TIME, BUT WOULD
04200			PUSH	SP,[0]	     ;BE INCLUDED IF NO RETURNS 
04300			PUSH	SP,[0]	     ;DONE ABOVE (RETURN NULL STRING)
04400	
04500	
04600	RECURSIVE INTEGER PROCEDURE P4(STRING A,B; INTEGER I,J);
04700		P4TEXT:	AOS	P4PAC
04800	
04900	BEGIN
05000	 STRING C,D; INTEGER K,L;
05100	 ...
     

00100	SAILON NO. 57.2					SAIL   17-49
00200	
00300	END "P4";
00400		P4EXIT:	SOS	P4PAC
00500			SUB	SP,[XWD =8,=8] ;[8]TAKE OFF LOCALS,PARAMS
00600			HRRI	TEMP,C		;[8]
00700			HRLI	TEMP,5(SP)	;[8]
00800			BLT	TEMP,D+1	;[8] RESTORE LOCAL STRINGS
00900	
01000			SUB	P,[XWD 6,6]	;[8] SAME FOR P-SIDE
01100			HRRI	TEMP,K		; (ALSO RETURN ADDR REMOVED)
01200			HRLI	TEMP,4(P)
01300			BLT	TEMP,TEMP03	;MUST EVEN SAVE TEMPS
01400			JRST	@3(P)		;RETURN
01500	
01600		P4:	ADD	P,[XWD 3,3]	;LEAVE ROOM FOR LOCALS 
01700			SKIPL	P		;CHECK PUSH-DOWN OVERFLOW
01800			PDLOV	P,		;[9]UUO TO SIMULATE PDL OV
01900			HRRI	TEMP,-2(P)	;[9]SAVE LOCALS
02000			HRLI	TEMP,TEMP03	; AND TEMPS
02100			BLT	TEMP,(P)
02200			<similarly for SP (string stack)>
02300			JRST	P4TEXT		;GO DO PROCEDURE
02400			<variables and such>
02500	
02600	
02700	
02800	RECURSIVE STRING PROCEDURE P5(STRING A,B);
02900	BEGIN
03000	 STRING C,D;
03100	 ...
03200	 RETURN(C);
03300			PUSHJ	P,P5POP	;[10]REMOVE STRING LOCALS,PARAMS
03400			PUSH	SP,C	;STRING RESULT
03500			PUSH	SP,C+1
03600			PUSHJ	P,ARREL	;ENOUGH TIMES IF ANY ARRAYS
03700			JRST	P5EXIT
03800	
03900	 RETURN(B);
04000			PUSHJ	P,P5POP
04100			PUSH	SP,3(SP)
04200			PUSH	SP,3(SP)	;RETURN PARAMETER
04300			JRST	P5EXIT
04400	
04500	 RETURN(A&"STR");
04600			POP	SP,1	;[11]ASSUME CAT ALREADY DONE
04700			POP	SP,0
04800			PUSHJ	P,P5POP
04900			PUSH	SP,0	;[11]RETURN VALUE
05000			PUSH	SP,1
05100			JRST	P5EXIT
     

00100	SAILON NO. 57.2					SAIL   17-49
00200	
00300	 
00400	 ...
00500	END "P5";
00600		P5EXIT:	SUB	P,[XWD 2,2] ;OR WHATEVER, SEE ABOVE
00700			...		     ;RESTORE LOCALS, ADJUST
00800			JRST	@3(P)	    ;RETURN
00900	
01000		P5:	<as above>
01100			...
01200	
01300		P5POP:	SUB	SP,[XWD =8,=8]	;[10] REMOVE STRING LOCALS,PARAMS
01400			HRRI	TEMP,C
01500			HRLI	TEMP,5(SP)
01600			BLT	TEMP,D+1
01700			POPJ	P,		;RETURN
01800	
01900	The main program has the following format:
02000	
02100	
02200	S.:	SKIPA		;NOT STARTED IN RPG MODE
02300		SETOM	RPGSW	;STARTED IN RPG MODE -- RPGSW A GLOBAL
02400		JSR	SAILOR	;INIT -- RETURNS BY PUSHJ P,@SAILOR
02500	
02600	  Comment ⊗ The main program looks like a non-recursive procedure
02700	    from here on, except for built-in arrays  ⊗
02800	
02900		POPJ	P,	;RETURN TO INIT, WHO EXITS
03000		<global variables, linkages>
03100		<non-String constants>
03200		XWD	0,,=8	;TYPICAL STRING CONSTANT
03300		POINT	7,.+1
03400		ASCII	/CONSTANT/
03500		<more String constants>
03600	
03700		END	S.	;STARTING ADDRESS FOR MAIN PROGRAM
03800	
     

00100	SAILON NO. 57.2					SAIL   17-50
00200	
00300	   
00400	   
00500	Discussion
00600	   
00700	   
00800	17-50.    
00900	
01000	[1]   There is for each procedure a word (PAC  for  Procedure  Active
01100	      Count)  which is incremented on procedure entry and decremented
01200	      on exit.  At one time, the String garbage collector  used  this
01300	      word.   It  may  again some time in the future.  At present the
01400	      counter is useful for determining the depth of recursion  (from
01500	      DDT).
01600	
01700	[2]   Non-String  procedures  return  their  results  in  1;  Fortran
01800	      returns  things  in  0;  String  results are returned on the SP
01900	      stack.
02000	
02100	[3]   An ARREL call is issued  for  each  block  (containing  arrays)
02200	      which  must  be  left  in  order to exit.  All arrays for these
02300	      blocks are released at this  time.   The  same  sort  of  thing
02400	      happens when a Go To statement leaves one or more blocks.
02500	
02600	[4]   Since the return address is on the top  of  the  P-stack,  with
02700	      parameters  buried  beneath,  a  subtract  and an indirect jump
02800	      replace the POPJ.  Procedures always adjust  the  stack  before
02900	      returning.
03000	
03100	[5]    String  temporaries  are  kept  in  the  SP   stack.    Others
03200	      occasionally  occupy  core  locations.  These are grouped with
03300	      the non-String variables to make saving and restoring  easy  in
03400	      recursive procedures.
03500	
03600	[6]   This is the Procedure Active  Count  word  (see  [1]).   It  is
03700	      placed  in  a  fixed  location  with respect to the String-link
03800	      block (below).  The  String  garbage  collector  could,  if  it
03900	      wished, see this count.
04000	
04100	[7]   A linked list, with its head in a reserved  cell  in  the  user
04200	      table (see User Table, 17-1) gives the String garbage collector
04300	      access to all String variables declared for each procedure; and
04400	      to all built-in String arrays.  Each entry on the list contains
04500	      three words: a PAC counter (currently ignored), a  word  giving
04600	      the  location  and  extent  of  the  String  descriptors  being
04700	      described, and the pointer (LNKWD) to  the  next  entry.   A  0
04800	      entry  ends  the  list.   The LINK pseudo-op (or the equivalent
04900	      code issued by SAIL) instructs the loader to create this  list.
05000	      The  LINKEND  pseudo-op  is  issued  in  the  SAILOR routine to
05100	      collect the address of the first list element.   This  is  then
     

00100	SAILON NO. 57.2					SAIL   17-50
00200	
00300	      transferred  to  the  user  table.   See  [Weiher]  for details
00400	      concerning the LINK block type.
00500	
00600	[8]   When a recursive procedure is called, all values for  variables
00700	      declared  in blocks internal to this procedure are saved in the
00800	      appropriate stack.  These are added "on top of" the  parameters
00900	      and  return  address  for the procedure.  At procedure exit the
01000	      stack pointer is adjusted to point below the  first  parameter.
01100	      Then  the proper BLT word is set up to restore all these locals
01200	      from the stack.  After the BLT is executed, that stack is ready
01300	      for procedure exit.
01400	
01500	[9]   Since SAIL is a one-pass compiler, it does not  know  how  many
01600	      locals a procedure has until all blocks for that procedure have
01700	      been  processed.   Therefore  the  entry  code  for   recursive
01800	      procedures  is  added last, followed by a jump to the procedure
01900	      text.
02000	
02100	[10]  When a String procedure returns a value, the String  parameters
02200	      and  locals  must  be  removed  from the stack before the value
02300	      (result) can be pushed on.  Since the total  number  of  String
02400	      locals  is  not  yet  known,  a routine like P5POP is called to
02500	      remove the unwanted values first.  Recursive String  procedures
02600	      must  contain  Return  Statements (see Return Statement, 5-20);
02700	      otherwise improper code will result.
02800	
02900	[11]  Once P5POP or its equivalent has been  executed,  the  previous
03000	      top of stack location is not known; the temp value is therefore
03100	      removed first and restored after the call.
03200	   
03300	   
03400	Procedure Calling Sequences
03500	   
03600	   
03700	17-51.    Again a case study is presented.  A procedure with  several
03800	internal procedures is presented to demonstrate the ridiculous number
03900	of possibilities.  Only the relevant code is  described.   Accumulator
04000	numbers  in  the  code  below  are  only examples -- other values are
04100	possible.  This list is not complete;  to  describe  all  cases  here
04200	would  take  more space than a copy of the code in SAIL which handles
04300	them.   Item  and  Set  parameters  behave  like  Integer  and   Real
04400	parameters as far as argument passing is concerned:
     

00100	SAILON NO. 57.2					SAIL   17-51
00200	
00300	
00400	
00500	PROCEDURE SUPER(REFERENCE STRING RPSTR;
00600			INTEGER PINT; REFERENCE INTEGER RPINT;
00700			REAL PROCEDURE PPAR;
00800			STRING PSTR1,PSTR2);
00900	BEGIN
01000	 INTEGER INT1,INT2; STRING STR1,STR2; REAL REL;
01100	 SAFE INTEGER  ARRAY ARR[2:10]; SAFE STRING ARRAY SARR[2:10];
01200	 INTEGER PROCEDURE INTP(INTEGER I,J);...;
01300	 PROCEDURE RINTP(REFERENCE INTEGER I);...;
01400	 PROCEDURE STRP(STRING A,B);...;
01500	 PROCEDURE RSTRP(REFERENCE STRING A);...;
01600	 PROCEDURE PROCP(PROCEDURE PARAM);...;
01700	 PROCEDURE ARRP(STRING ARRAY X);...;
01800	
01900	
02000	 INT1←PINT↑2 + RPINT↑2 - 3;
02100			MOVE	1,-3(P)		;RELATIVE LOC OF PINT
02200			IMUL	1,1
02300			MOVE	2,@-2(P)	;RPINT's ADDRESS IS IN STACK
02400			IMUL	2,2
02500			ADD	2,1		;SUM
02600			SUBI	2,3		;RESULT LEFT IN 2
02700	
02800	REL←INTP(INT1,PINT);
02900			PUSH	P,2		;INT1 STILL IN 2
03000			PUSH	P,-4(P)		;[1]ADJUST FOR PREV PUSH
03100			MOVEM	2,INT2		;[2]STORE CURRENT ACS BEFORE CALL
03200			PUSHJ	P,INTP		;CALL PROCEDURE
03300			FLOAT	1,1		;CONVERT TO REAL -- REL IS IN 1
03400	
03500	RINTP(INT1);
03600			PUSH	P,[INT1]	;ADDRESS OF INT1
03700			MOVEM	1,REL		;PREVIOUS RESULT
03800			PUSHJ	P,RINTP
03900	
04000	RINTP(PINT);
04100			MOVEI	3,-3(P)		;ADDRESS OF PINT
04200			PUSH	P,3
04300			PUSHJ	P,RINTP
04400	
04500	RINTP(RPINT);
04600			PUSH	P,-2(P) 	;PASS ON ADDR OF RPINT
04700			PUSHJ	P,RINTP
04800	
04900	INT2←INTP(INT1,ARR[PINT]);
05000			PUSH	P,INT1
05100			MOVE	4,-4(P)		;PINT
     

00100	SAILON NO. 57.2					SAIL   17-51
00200	
00300			MOVE	5,ARR
00400			ADD	4,-4(5)		;BASE ADDR OF ARR
00500			PUSH	P,(4)
00600			PUSHJ	P,INTP		;RESULT IN 1
00700	
00800	RINTP(ARR[PINT]);
00900			MOVE	6,PINT
01000			MOVE	7,ARR
01100			ADD	6,-4(7)
01200			PUSH	P,6		;ADDRESS
01300			MOVEM	1,INT2
01400			PUSHJ	P,RINTP
01500	
01600	STRP(STR1&"CON",PSTR1);
01700			PUSH	SP,STR1
01800			PUSH	SP,STR1+1
01900			PUSH	SP,CONAD	;ADDRESS OF DSCRPTR FOR "CON"
02000			PUSH	SP,CONAD+1
02100			PUSHJ	P,CAT		;LEAVE CONCATENATE IN STACK
02200			PUSH	SP,-4(SP)	;PUT STR1 ON TOP
02300			PUSH	SP,-4(SP)
02400			PUSHJ	P,STRP
02500	
02600	RSTRP(STR1);
02700			PUSH	P,[STR1+1]	;ALL REF PARAMS TO P-STACK
02800			PUSHJ	P,RSTRP
02900	
03000	RSTRP(RPSTR);
03100			PUSH	P,-4(P)		;PASS REFERENCE ALONG;
03200			PUSHJ	P,RSTRP
03300	
03400	RSTRP(PSTR2);
03500			HRROI	10,(SP)		;[3]RH→2D WORD OF PSTR2
03600			PUSH	P,10
03700			PUSHJ	P,RSTRP
03800	
03900	PROCP(RINTP);
04000			PUSH	P,[RINTP]	;PARAMETRIC PROCEDURE
04100			PUSHJ	P,PROCP
04200	
04300	ARRP(SARR);
04400			PUSH	P,SARR		;THIS IS EFFECTIVELY A REFERENCE CALL
04500			PUSHJ	P,ARRP
04600	
     

00100	SAILON NO. 57.2					SAIL   17-52
00200	
00300	   
00400	   
00500	Discussion
00600	   
00700	   
00800	17-52.    
00900	
01000	[1]   Counts are  maintained  of  the  current  number  of  actual
01100	      parameters  (during  a procedure call) on each stack.  These
01200	      counts must be added to  the  parameter  indices  to  access
01300	      parameters of the procedure doing the calling.
01400	
01500	[2]   Whenever a SAIL procedure is called, all accumulators except
01600	      SP ('16) and P ('17) are available for its use.
01700	
01800	[3]   Some  String  operations  require  that  the  left  half  of
01900	      pointers   to   descriptors   be  negative.   Therefore  any
02000	      operation which obtains a String descriptor address  does  a
02100	      HRRO  or  HRROI  to accomplish this.  In this case it is not
02200	      necessary, but it won't  hurt  anything.   String  reference
02300	      parameters  always point to the second word of the String in
02400	      question.
02500	   
     

00100	SAILON NO. 57.2					SAIL   18-1
00200	
00300	                              SECTION 18
00400	                                    
00500	                     APPENDIX -- USEFUL SUMMARIES
00600	                                    
00700	   
00800	   
00900	ARITHMETIC TYPE-CONVERSION TABLE
01000	   
01100	   
01200	18-1.    
01300	   
01400	   
01500	   
01600	OPERATION     ARG1   ARG2   ARG1'  ARG2'  RESULT
01700	   
01800	+ -           INT    INT    INT    INT    INT*
01900	* ↑ %         REAL   INT    REAL   REAL   REAL
02000	              INT    REAL   REAL   REAL   REAL
02100	              REAL   REAL   REAL   REAL   REAL
02200	   
02300	LAND LOR      INT    INT    INT    INT    INT
02400	EQV XOR       REAL   INT    REAL   INT    REAL
02500	              INT    REAL   INT    REAL   INT
02600	              REAL   REAL   REAL   REAL   REAL
02700	   
02800	LSH ROT       INT    INT    INT    INT    INT
02900	              REAL   INT    REAL   INT    REAL
03000	              INT    REAL   INT    INT    INT
03100	              REAL   REAL   REAL   INT    REAL
03200	   
03300	/             INT    INT    REAL   REAL   REAL
03400	              REAL   INT    REAL   REAL   REAL
03500	              INT    REAL   REAL   REAL   REAL
03600	              REAL   REAL   REAL   REAL   REAL
03700	   
03800	MOD DIV       INT    INT    INT    INT    INT
03900	              REAL   INT    INT    INT    INT
04000	              INT    REAL   INT    INT    INT
04100	              REAL   REAL   INT    INT    INT
04200	   
04300	* Unless ARG2 is <0 for the operator ↑
     

00100	SAILON NO. 57.2					SAIL   18-2
00200	
00300	   
00400	   
00500	SAIL RESERVED WORDS
00600	   
00700	   
00800	18-2.    
00900	   
01000	ABS AND ANY ARRAY ARRAY_PDL ASSOC BBPP  BEGIN  BOOLEAN  CASE  COMMENT
01100	CONTINUE  COP  CVI  CVN  DATUM DEFINE DELETE DIV DO DONE DPB ELSE END
01200	ENTRY EQV ERASE EXTERNAL FALSE FIRST FOR FOREACH FORTRAN FORWARD FROM
01300	GEQ  GLOBAL  GO  GOTO  IBP IDPB IF ILDB IN INF INTEGER INTER INTERNAL
01400	ISTRIPLE  ITEM  ITEMVAR  LABEL  LAND  LDB  LENGTH  LEQ  LET   LIBRARY
01500	LOAD_MODULE  LNOT  LOP  LOR LSH MAKE MAX MESSAGE MIN MOD NEEDNEXT NEQ
01600	NEXT NEW NEW_ITEMS  NOT  NULL  OF  OR  OWN  PHI  PNAMES  PRELOAD_WITH
01700	PROCEDURE  PUT  QUICK_CODE  REAL  RECURSIVE  REFERENCE REMOVE REQUIRE
01800	RETURN ROT SAFE SECOND SEGMENT_NAME SEGMENT_FILE SET SETC SETO  SHORT
01900	START_CODE  STEP STRING STRING_PDL STRING_SPACE SOURCE_FILE SUCH SWAP
02000	SYSTEM_PDL THAT THEN THIRD TO TRUE UNTIL VALUE WHILE XOR
02100	   
02200	   
02300	SAIL PRE-DECLARED IDENTIFIERS
02400	   
02500	   
02600	18-3.    
02700	   
02800	ARRBLT ARRINFO ARRTRAN ARRYIN  ARRYOUT  BACKUP  BREAKSET  CALL  CLOSE
02900	CLOSIN  CLOSO  CLRBUF  CODE CVASC CVD CVE CVF CVFIL CVG CVIS CVO CVOS
03000	CVS CVSI CVSIX CVSTR CVXSTR  ENTER  EQU  FILEINFO  GETCHAN  GETFORMAT
03100	INCHRW  INCHRS  INCHSL INCHWL INSTR INSTRL INSTRS INPUT INTIN INTSCAN
03200	LINOUT LODED LOOKUP MTAPE OPEN OUT OUTCHR OUTSTR PTCHRS PTCHRW PTIFRE
03300	PTOCNT  PTOCHS PTOCHW PTOSTR PTYALL PTYGET PTYIN PTYREL PTYSTR REALIN
03400	REALSCAN RELEASE RENAME SCAN SETBREAK SETFORMAT STRBRK  TTYIN  TTYINL
03500	TTYINS WORDIN WORDOUT USERCON USERERR USETI USETO
     

00100	SAILON NO. 57.2					SAIL   18-4
00200	
00300	   
00400	   
00500	CHARACTER-IDENTIFIER EQUIVALENCES
00600	   
00700	   
00800	18-4.    
00900	
01000	
01100		CHARACTER		RESERVED WORD
01200	
01300		    ∧			   AND
01400		    ≡			   EQV	
01500		    ¬			   NOT
01600		    ∨			   OR
01700		    ⊗			   XOR	
01800		    ∞			   INF
01900		    ε			   IN
02000		    |			   SUCH THAT
02100		    ≠			   NEQ
02200		    ≤			   LEQ
02300		    ≥			   GEQ
02400		    {			   SETO
02500		    }			   SETC
02600		    ∪			   UNION
02700		    ∩			   INTER
02800		    `			   ASSOC
02900		    ↔			   SWAP
03000		    _			   !
03100	
     

00100	SAILON NO. 57.2					SAIL   18-5
00200	
00300	   
00400	   
00500	PARAMETERS TO THE OPEN FUNCTION
00600	   
00700	   
00800	18-5.    
00900	   
01000	
01100	CHANNEL   System Data Channel, 0-'17
01200	
01300	DEVICE    string giving device name
01400	
01500	MODE      data mode, bits 18-21, 23 enable error returns
01600	
01700	INBUFS    number of input buffers, lh buffer size if ≠0
01800	
01900	OUTBUFS   number of output buffers
02000	
02100	COUNT     text input count (reference)
02200	
02300	BRCHAR    break char variable (reference)
02400	
02500	EOF       end-of-file and IO error flag (reference)
     

00100	SAILON NO. 57.2					SAIL   18-6
00200	
00300	   
00400	   
00500	BREAKSET MODES
00600	   
00700	   
00800	18-6.    
00900	
01000	I         (Inclusion) string is set of break chars
01100	
01200	X         (eXclusion) string of all non-break chars
01300	
01400	O         (Omit) string of characters to be omitted from result
01500	             
01600	
01700	S         (skip) break char appears only in BRCHAR variable
01800	
01900	A         (Append) break char is last char of result string
02000	
02100	R         (Retain) break char is first char of next string
02200	             
02300	
02400	P         (Pass) line numbers appear in input without warning
02500	
02600	N         (No numbers) line numbers and the tabs that follow  them
02700	          are removed.
02800	
02900	L         (Line no break) line numbers cause input break.   BRCHAR
03000	          is negative.  Next input gets line no characters.
03100	
03200	E         (Erman) line numbers cause input break.  Negated line no
03300	          returned in BRCHAR.  Line no removed from input.
03400	
03500	D         (Display) after this appears, each line no is listed  on
03600	          the display (if TTY is a DPY) as it is dealt with.
     

00100	SAILON NO. 57.2					SAIL   18-7
00200	
00300	   
00400	   
00500	MTAPE COMMANDS
00600	   
00700	   
00800	18-7.    
00900	             
01000	             
01100	
01200	MODE      FUNCTION
01300	             
01400	
01500	"A"       Advance past one tape mark (or file)
01600	
01700	"B"       Backspace past one tape mark
01800	
01900	"F"       Advance one record
02000	
02100	"R"       Backspace one record
02200	
02300	"W"       Rewind tape
02400	
02500	"E"       Write tape mark
02600	
02700	"U"       Rewind and unload
02800	             
     

00100	SAILON NO. 57.2					SAIL   18-8
00200	
00300	   
00400	   
00500	COMMAND SWITCHES
00600	   
00700	   
00800	18-8.    
00900	
01000	D         double size of define pushdown stack
01100	
01200	numL      listing control -- num>0 becomes listing starting  addr.
01300	          num=-1  starts  listing  after current DDT size.  num=-2
01400	          starts listing after current RAID size.
01500	
01600	numM      initial debugging mode set to num
01700	
01800	P         double size of system pushdown list
01900	
02000	Q         double size of string pushdown list
02100	
02200	R         double size of parse pushdown list
02300	
02400	numS      set size of string space to num
02500	
02600	C         create CREF (cross-reference) input file.
02700	
02800	numF      enable various listing formats.
02900	   
03000	   
03100	DEBUGGING MODES
03200	   
03300	   
03400	18-9.    
03500	
03600	1         display before executing each code generation routine
03700	
03800	2         don't display, but remain enabled for  asynchronous  and
03900	          line breaks
04000	
04100	3         display before each production is compared
04200	
04300	4         continue from type 1 and 3 modes automatically
04400	
04500	5         just display input file as it goes past
04600	
04700	6         disable debugging mechanism (started in this mode unless
04800	          an M switch appears).
     

00100	SAILON NO. 57.2					SAIL   18-10
00200	
00300	   
00400	   
00500	VALID RESPONSES TO ERROR MESSAGES
00600	   
00700	   
00800	18-10.    
00900	
01000	CR        (carriage return) try to continue
01100	
01200	LF        (line feed) continue automatically  --  don't  stop  for
01300	          user go-ahead after each message
01400	
01500	S         restart
01600	
01700	X         exit -- close all files, return to monitor
01800	
01900	L         look at stacks -- of interest only to compiler fixers
02000	
02100	E         edit.  Follow by CR to get file the compiler is  working
02200	          on (or last thing edited, for runtime routines).  Follow
02300	          with <name> CR to edit <name>.
02400	
02500	D         go to DDT or RAID
     

00100	SAILON NO. 57.2					SAIL   18-11
00200	
00300	   
00400	   
00500	NON-FATAL ERROR, EXCEPTIONAL CONDITION RETURN CODES
00600	   
00700	18-11.    
00800	
00900	
01000	ROUTINE    CODE LOCATION        CONDITIONS, CODE VALUES 
01100	
01200	CALL      _SKIP_         set TRUE if the UUO skips, FALSE otherwise
01300	
01400	CODE      _SKIP_         set TRUE if the constructed instruction
01500	                         skips, FALSE otherwise
01600	
01700	CVFIL     _SKIP_         set TRUE if the file input is invalidly
01800	                         specified (wrong punctuation, order, etc.),
01900	                         FALSE otherwise.
02000	
02100	CVIS      FLAG param     set TRUE if no PNAME exists for  this  Item,
02200	                         FALSE if CVIS succeeds.
02300	
02400	CVSI      FLAG param     set TRUE if no Item exists with this  String
02500	                         as PNAME, FALSE if CVSI succeeds.
02600	
02700	ENTER     FLAG param     set FALSE if the ENTER succeeds.  Otherwise,
02800	                         the  left half is made -1.  Then if the file
02900	                         name was invalid, the  right  half  is  made
03000	                         '10.   Otherwise it is set to some code from
03100	                         0 to 7,  depending  on  the  type  of  ENTER
03200	                         failure.   These  codes  are the same as the
03300	                         ENTER UUO codes in [Moorer].  If  error  '10
03400	                         (invalid   spec.)   is  returned,  an  error
03500	                         message (non-fatal) will  also  be  printed,
03600	                         unless  you are enabled for user handling of
03700	                         this error (see I/O below).
03800	
03900	GETCHAN   result         <0 if no channel is available.
04000	
04100	INCHRS    result         <0 if no characters are waiting.
04200	
04300	INCHSL    FLAG param     ≠0 if no characters are waiting.
04400	
04500	INSTRS    FLAG param     ≠0 if no characters are waiting.
     

00100	SAILON NO. 57.2					SAIL   18-11
00200	
00300	
00400	I/O       EOF vbl.       0 if no exceptional conditions  occurred  in
00500	                         an  I/O operation.  Otherwise, the left half
00600	                         has certain bits turned on, indicating the
00700	                         error: 400000  is  a  catchall  --  improper
00800	                         mode.
00900	                         200000 means parity error occurred.
01000	                         100000 means a data error occurred.
01100	                         40000 means "Record number out of bounds".
01200	                         20000 means End of File (input only).
01300	                         You  are always enabled for bit 20000 (EOF).
01400	                         However, to be allowed to handle any of  the
01500	                         others,  you  must turn on the corresponding
01600	                         bit in the right half of the  MODE  word  in
01700	                         the OPEN for this channel.  In addition, the
01800	                         10000 bit is used to enable user handling of
01900	                         invalid   file   specifications   to  ENTER,
02000	                         LOOKUP, and RENAME (see above).  '7500017 in
02100	                         the  MODE parameter would enable a dump mode
02200	                         file for user handling of ALL I/O errors  on
02300	                         this  channel.  If you are not enabled for a
02400	                         given error, an error message (which may  or
02500	                         may  not  be fatal) will be printed, and the
02600	                         error  code  word  set  as  indicated.    In
02700	                         addition,   the  number  of  words  actually
02800	                         transferred is stored in the right  half  of
02900	                         this variable for ARRYIN, ARRYOUT.
03000	
03100	LOOKUP    FLAG param     same as ENTER.
03200	
03300	OPEN      EOF vbl        if 0 on entry, prints fatal error message if
03400	                         OPEN  fails.  If ≠0 on entry, always returns
03500	                         to user -- still ≠0 if OPEN failed, 0 if  it
03600	                         succeeded.
03700	
03800	RENAME    FLAG param     same as ENTER.
03900	
04000	TTYINS    FLAG param     same as INSTRS.
     

00100	SAILON NO. 57.2					SAIL   18-11
00200	
00300	
00400	substrings _SKIP_        consider ST[X TO Y]. If Y>LENGTH(ST), Y←
00500				 LENGTH(ST).  If Y<0, Y←0; rh(_SKIP_)←-1 with
00600	                         both. If X<1, X←1.   If  X>Y it  is  set  to
00700	                         Y+1 (guaranteeing a null String result).  In
00800	                         either case, lh(_SKIP_) is set to  -1.   The
00900	                         ST[X  FOR  Y] case is first converted to the
01000	                         other case, then executed.
01100	
01200	You should also refer to the table for Input, 12-40,  describing  the
01300	                         various  combinations  of the BRCHAR and EOF
01400	                         variables and their meanings.
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	                                          SECTION 19
00400	                                                 
00500	                                         BIBLIOGRAPHY
00600	                                                 
00700	                            
00800	                            
00900	                         19-1.    
01000	
01100	
01200	REFERENCE           DESCRIPTION
01300	
01400	
01500	Feldman             Feldman, J.A.  and Rovner, P.D.   An  Algol-Based
01600	                    Associative  Language,  Comm.   ACM  12,  8 (Aug.
01700	                    1969), 439-449.
01800	
01900	
02000	Moorer               Moorer,  J.A.   Stanford  A-I  Project   Monitor
02100	                    Manual, Sailons 54 and 55 (Sep.  1969).
02200	
02300	
02400	Weiher              Weiher, W.F.   Loader  Input  Format,  Sailon  46
02500	                    (Oct.  1968).
02600	
02700	
02800	Savitzky            Savitzky, S.R.   Son  of  Stopgap,  Sailon  50.1,
02900	                    (Sep.   1969),  a revision of Stopgap, Sailon 50,
03000	                    by W.F.  Weiher.
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	INDEX
00400	
00500	10- 1	<λ_associative_expr>
00600	10- 1	<λ_derived_set>
00700	10- 1	<λ_item_expr_list>
00800	10- 1	<λ_item_expression>
00900	10- 1	<λ_set_expression>
01000	10- 1	<λ_set_factor>
01100	10- 1	<λ_set_primary>
01200	10- 1	<λ_set_term>
01300	 7- 1	<λ_triple>
01400	10- 1	<λ_triple>
01500	 9-54	Abs
01600	 8- 1	<ac_field>
01700	 6- 1	<actual_parameter>
01800	 6- 1	<actual_parameter_list>
01900	 9- 1	<actual_parameter_list>
02000	 9- 1	<actual_parameter>
02100	13- 9	Actual Parameter Expansion
02200	 6- 4	Actual Parameters
02300	 9- 1	<adding_expression>
02400	 9- 1	<adding_operator>
02500	 9-30	Adding Expressions
02600	 8- 1	<address>
02700	 8- 1	<addresses>
02800	 4- 1	<algebraic_assignment>
02900	 9- 1	<algebraic_expression>
03000	 9- 1	<algebraic_relational>
03100	 3- 1	<algebraic_type>
03200	 9- 1	<algebraic_variable>
03300	 9	ALGEBRAIC EXPRESSIONS
03400	 9-15	Algebraic Expressions
03500	10- 7	ANY Construct
03600	18	APPENDIX -- USEFUL SUMMARIES
03700	11-15	Arithmetic Constants
03800	 9-21	Arithmetic Type Conversions
03900	 3- 1	<array_declaration>
04000	 3- 1	<array_list>
04100	 3- 1	<array_segment>
04200	17-37	Array Allocation
04300	 3-25	Array Declarations
04400	17-35	ARRAY IMPLEMENTATION
04500	 3-31	Arrays, outer block
04600	 3-30	Arrays, OWN
04700	 3-26	Arrays, SAFE declaration
04800	 3-27	Arrays, storage convention
04900	12-112	Arrblt
05000	12-110	Arrinfo
05100	12-114	Arrtran
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	12-50	Arryin
00400	12-55	Arryout
00500	16-12	Assembly Language Procedures
00600	 8	ASSEMBLY LANGUAGE STATEMENTS
00700	 4- 1	<assignment>
00800	 9- 1	<assignment_expression>
00900	 4- 1	<assignment_statement>
01000	 9- 4	Assignment Expressions
01100	 4- 7	Assignment statement, DATUM
01200	 4- 3	Assignment statement, semantics
01300	 4- 8	Assignment statement, Swap
01400	 4	ASSIGNMENT STATEMENTS
01500	 7- 1	<associative_context>
01600	10- 1	<associative_expression>
01700	10- 1	<associative_operator>
01800	 7- 1	<associative_statement>
01900	 7-18	Associative context, satisfaction
02000	11	BASIC CONSTRUCTS
02100	19	BIBLIOGRAPHY
02200	14- 1	<binary_name>
02300	 7- 1	<binding_list>
02400	 2- 1	<block>
02500	 2- 1	<block_head>
02600	 2- 1	<block_name>
02700	 2- 9	Block Names
02800	 3-20	Block structure, for items
02900	 3-14	Boolean, declaration
03000	 9- 1	<boolean_expression>
03100	10- 9	Boolean constructs, for LEAP
03200	 9-10	Boolean Expression, anomaly
03300	 7-16	Boolean expressions, if FOREACH specifications
03400	 9-56	Boolean Primaries
03500	 3- 1	<bound_pair>
03600	 3- 1	<bound_pair_list>
03700	 9- 1	<bounded_expression>
03800	 9-29	Bounded Expressions
03900	 7-11	Bracketed Triples
04000	 9-57	Bracketed triples, ISTRIPLE
04100	10- 5	Bracketed triples, selectors
04200	 7-14	Breakpoints, MAKE and ERASE
04300	12-22	Breakset
04400	 4- 1	<byte_statement>
04500	12-127	Byte pointers, creation
04600	 4-10	Byte statements
04700	12-118	Call
04800	17-12	Caninc
04900	 9- 1	<case_expression>
05000	 5- 1	<case_statement>
05100	 5- 1	<case_statement_head>
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	 9- 6	Case Expressions
00400	 5-18	Case Statements
00500	12-10	Close, Closin, Closo
00600	12-116	Code
00700	 8- 1	<code_begin>
00800	 8- 1	<code_block>
00900	 8- 1	<code_head>
01000	 8- 1	<code_tail>
01100	14- 1	<command_line>
01200	14- 1	COMMAND FORMAT
01300	 2-10	Comment
01400	11-24	Comments
01500	14	COMPILER OPERATION
01600	 2- 1	<compound_statement>
01700	 2- 1	<compound_tail>
01800	 9-38	Concatenation Operator
01900	 9- 1	<conditional_expression>
02000	 5- 1	<conditional_statement>
02100	 9- 2	Conditional Expressions
02200	 5- 2	Conditional Statements
02300	 5- 6	Conditional Statements, ambiguity
02400	11-15	Constants, arithmetic
02500	11-16	Constants, octal
02600	11-17	Constants, real
02700	11-19	Constants, string
02800	 7- 8	Construction, definition
02900	10- 1	<construction_item_prim>
03000	 5- 1	<continue_statement>
03100	 5-30	Continue Statement
03200	 4- 6	Conversions, algebraic
03300	 9-21	Conversions, algebraic
03400	 9-12	Conversions, Boolean to Integer
03500	 3-36	Conversions, for preloaded arrays
03600	 3-17	Conversions, string
03700	 9-27	Conversions, strings
03800	 9-11	Conversions, to BOOLEAN
03900	10- 4	COP, of set
04000	17-13	Corbig
04100	17- 6	Corget
04200	17-11	Corinc
04300	17-10	Correl
04400	12-105	Cvasc
04500	12-101	Cvd
04600	12-92	Cve, Cvf, Cvg
04700	12-109	Cvfil
04800	10- 8	CVI
04900	12-84	Cvis
05000	 9-52	Cvn
05100	12-103	Cvo
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	12-82	Cvos
00400	12-80	Cvs
00500	12-86	Cvsi
00600	12-107	Cvsix
00700	12-97	Cvstr
00800	12-99	Cvxstr
00900	 7- 3	DATUM, use of
01000	 4- 7	Datum Assignments
01100	11- 6	Datums
01200	15- 9	DEBUGGING
01300	14-14	Debugging modes
01400	 3- 1	<declaration>
01500	 2- 3	Declarations
01600	 3	DECLARATIONS
01700	 8- 3	Declarations in Code Blocks
01800	 3- 1	<define_body>
01900	 3- 1	<define_identifier>
02000	 3- 1	<define_specification>
02100	 3-56	Define Specification
02200	13- 1	Defining Macros
02300	 3- 1	<definition>
02400	 3- 1	<definition_list>
02500	12-90	Del_Pname
02600	 7-10	DELETE
02700	14- 1	<device_name>
02800	 9- 1	<disjunctive_expression>
02900	 9-18	Disjunctive Expressions
03000	 8- 7	Distinctions Between START_CODE and QUICK_CODE
03100	 5- 1	<do_statement>
03200	 5-17	Do Statement
03300	 5- 1	<done_statement>
03400	 5-24	Done Statement
03500	 4-10	DPB
03600	 7- 1	<element>
03700	 2- 1	<entry_specification>
03800	 2-11	Entry Specifications
03900	12-73	Equ
04000	 7-13	ERASE
04100	 7-13	ERASE, restriction
04200	14-19	ERROR MESSAGES
04300	 5	EXECUTION CONTROL STATEMENTS
04400	12	EXECUTION TIME ROUTINES
04500	 9- 1	<expression>
04600	 9- 1	<expression_list>
04700	 9-14	Expression Evaluation Rules
04800	 3- 2	EXTERNAL declaration
04900	 3-47	External Procedures
05000	 9- 1	<factor>
05100	 9-39	Factors
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	11-18	FALSE, definition
00400	14- 1	<file_ext>
00500	14- 1	<file_name>
00600	 3- 1	<file_spec>
00700	14- 1	<file_spec>
00800	10- 5	FIRST, of bracketed triple
00900	 5- 1	<for_list>
01000	 5- 1	<for_list_element>
01100	 5- 1	<for_statement>
01200	 5-11	For Statements
01300	 7-19	FOREACH specification, evaluation
01400	 7-15	FOREACH Statement
01500	 7-21	FOREACH statement, efficiency considerations
01600	 7-20	FOREACH statement, harsh warning
01700	 7-22	FOREACH statement, restrictions and warnings
01800	 3- 1	<formal_param_decl>
01900	 3- 1	<formal_parameter_list>
02000	 3- 1	<formal_type>
02100	 3-39	Formal Parameters
02200	 3-54	FORTRAN, actual parameters
02300	 3-49	FORTRAN, declaration
02400	 6-12	Fortran Procedures
02500	16-11	Fortran Procedures
02600	 3- 2	FORWARD declaration
02700	 3-42	Forward Procedure Declarations
02800	 9- 1	<function_designator>
02900	 9-47	Function Designators
03000	11-12	Functions, predeclared
03100	12-12	Getchan
03200	12-78	Getformat
03300	 5- 1	<go_to_statement>
03400	 3-54	Go To, restriction
03500	 5- 8	Go To Statements
03600	 5- 8	Go To Statements, restrictions
03700	12- 6	I/O ROUTINES
03800	 4-10	IBP
03900	 3- 1	<id_list>
04000	11- 7	Identifiers
04100	 4-10	IDPB
04200	 5- 1	<if_statement>
04300	 5- 4	If Statement
04400	 5- 5	If ... Else Statement
04500	 9-58	ILDB
04600	17	IMPLEMENTATION INFORMATION
04700	 8- 1	<index_field>
04800	 8- 1	<indexed_address>
04900	 2- 8	Inner block
05000	12-40	Input
05100	 8- 1	<instruction>
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	 3-13	Integers, range
00400	 3- 2	INTERNAL declaration
00500	 3-48	Internal procedures
00600	10- 2	Intersection, sets
00700	 1	INTRODUCTION
00800	 9-57	ISTRIPLE
00900	 3-54	ITEM, procedure
01000	 4- 1	<item_assignment>
01100	10- 1	<item_primary>
01200	 3- 2	ITEM ARRAYS, nonexistence
01300	10- 4	Item Constructs
01400	 3-18	Item Declarations
01500	 3-20	Item Genesis
01600	10- 5	Item Selectors
01700	 3-19	Items
01800	10- 6	Items, dynamic NEW
01900	 7- 4	ITEMS, storage of instances
02000	10- 1	<itemvar_variable>
02100	 3-22	Itemvar Declarations
02200	 3-23	Itemvars, binding in FOREACH
02300	 7-17	ITEMVARS, binding in FOREACH specifications
02400	 7-15	ITEMVARS, binding in FOREACH statements
02500	 7-23	ITEMVARS, in FOREACH statement
02600	 7- 4	ITEMVARS, use
02700	 3- 1	<label_declaration>
02800	 5- 1	<label_identifier>
02900	 3- 4	Label use
03000	 3-54	Labels, as actual parameters
03100	 9-58	LDB and ILDB
03200	 7- 2	LEAP, introduction
03300	 7- 7	LEAP, restrictions
03400	 9- 1	<leap_relational>
03500	10- 1	<leap_relational>
03600	 7- 1	<leap_statement>
03700	 3- 1	<leap_type>
03800	10- 9	LEAP Booleans
03900	 7	LEAP STATEMENTS 
04000	 9-50	Length
04100	12-116	LIBERATION-FROM-SAIL ROUTINES
04200	12- 1	Library, runtime
04300	12-46	Linout
04400	14- 1	<listing_name>
04500	 8- 1	<literal>
04600	 9-53	Lnot
04700	15- 1	LOADING AND STARTING SAIL PROGRAMS
04800	 9-30	Logical Expressions
04900	12-17	Lookup, Enter
05000	 7- 1	<loop_statement>
05100	 9-51	Lop
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	10- 4	LOP, of set
00400	17-28	Lop Details
00500	 3- 1	<lower_bound>
00600	13- 6	Macro Parameters
00700	16- 2	Main Program
00800	 7-11	MAKE
00900	 7-13	MAKE, restriction
01000	 8- 4	Meaning of Instruction Operands
01100	12-57	Mtape
01200	 9- 1	<mult_operator>
01300	 9- 1	<negated_expression>
01400	10- 6	NEW_ITEM Declaration
01500	12-88	New_Pname
01600	10- 6	NEW Items
01700	 5- 1	<next_statement>
01800	 5-26	Next Statement
01900	18-11	NON-FATAL ERROR, EXCEPTIONAL CONDITION RETURN CODES
02000	11-21	NULL, definition
02100	 3-13	Numeric Declarations
02200	 8- 1	<opcode>
02300	12- 6	Open
02400	12-45	Out
02500	 2- 8	Outer block
02600	10- 3	PHI, the empty set
02700	12-126	Point
02800	 9-13	Precedence of Algebraic Operators
02900	 3- 1	<preload_element>
03000	 3- 1	<preload_list>
03100	 3- 1	<preload_specification>
03200	 3-33	Preload Specifications
03300	 9-40	Primaries
03400	 9- 1	<primary>
03500	 3- 1	<procedure_body>
03600	 3- 1	<procedure_declaration>
03700	 3- 1	<procedure_head>
03800	 6- 1	<procedure_statement>
03900	 3- 5	Procedure body, emptiness
04000	17-51	Procedure Calling Sequences
04100	 6- 4	Procedure Calls, actual parameters
04200	 6- 2	Procedure Calls, semantics
04300	 3-38	Procedure Declarations
04400	17-48	PROCEDURE IMPLEMENTATION
04500	 6	PROCEDURE STATEMENTS
04600	 6-10	Procedures, as actual parameters
04700	 3-53	Procedures, defaults in declarations
04800	 3-51	Procedures, parametric
04900	 3-54	Procedures, restrictions
05000	 2- 1	<program>
05100	 2- 9	Program name, for DDT
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	15	PROGRAM OPERATION
00400	16	PROGRAM STRUCTURE
00500	 2	PROGRAMS, BLOCKS, STATEMENTS
00600	14- 1	<proj_prog>
00700	12-70	Pseudo-teletype functions (Stanford only)
00800	 7- 9	PUT, use
00900	12-61	Realin, Intin
01000	 3-13	Reals, range
01100	12-66	Realscan, Intscan
01200	 3- 2	RECURSIVE declaration
01300	 3-44	Recursive Procedures
01400	 3-39	REFERENCE
01500	 3-53	REFERENCE
01600	 6- 6	REFERENCE, actual parameters
01700	 9- 1	<relational_expression>
01800	 9- 1	<relational_operator>
01900	 9-19	Relational Expressions
02000	12-14	Release
02100	 7- 9	REMOVE, use
02200	12-21	Rename
02300	10- 6	REQUIRE, new_items
02400	 3- 1	<require_element>
02500	 3- 1	<require_list>
02600	 3-57	REQUIRE declaration
02700	 3- 1	<requirement>
02800	 3-57	Requirements
02900	11-10	Reserved words, list of
03000	11-11	Reserved words, "Global Model"
03100	 7- 8	Retrieval, definition
03200	10- 1	<retrieval_item_prim>
03300	 9-47	RETURN, value of function
03400	 5- 1	<return_statement>
03500	 5-20	Return Statement
03600	14-12	Rpg Mode
03700	11-12	Runtime routines, list of
03800	11-13	Runtime routines, Stanford Only
03900	 3- 2	SAFE declaration
04000	 7-18	Satisfiers, of associative context
04100	 7-19	Satisfiers, of associative context
04200	12-43	Scan
04300	 3- 8	Scope of declarations
04400	10- 5	SECOND, of bracketed triple
04500	10- 1	<selector>
04600	16- 7	Separately Compiled Procedures
04700	 4- 1	<set_assignment>
04800	10- 1	<set_expression>
04900	 7- 1	<set_statement>
05000	10- 1	<set_variable>
05100	10	SET AND ASSOCIATIVE EXPRESSIONS
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	 3-24	Set Declarations
00400	10- 2	Set Expressions
00500	10- 3	Set Primaries
00600	12-35	Setbreak
00700	12-75	Setformat
00800	10- 3	Sets, derived from associations
00900	 7-15	SETS, in FOREACH specifications
01000	 7- 5	SETS, use
01100	 9-24	Short Integer↔Real Conversions
01200	 8- 1	<simple_address>
01300	 9- 1	<simple_expression>
01400	 9- 9	Simple Expressions
01500	 3- 1	<simpler_formal_type>
01600	14- 1	<slashed_switch_list>
01700	14- 1	<source_list>
01800	 3- 1	<space_spec>
01900	 9-45	Special Length Operator (∞)
02000	15- 2	Starting the Program -- Normal Operation
02100	15- 3	Starting the Program in "RPG" Mode
02200	15- 4	Starting the Program with Allocation Modifications
02300	 2- 1	<statement>
02400	 2- 6	Statements
02500	12-37	Stdbrk
02600	14-22	STORAGE ALLOCATION
02700	17- 5	Storage Allocation Routines
02800	17- 1	STORAGE LAYOUT
02900	 9-27	String-Arithmetic Conversions
03000	 9- 1	<string_expression>
03100	17-33	String-Oriented Machine Language Routines
03200	 9- 1	<string_variable>
03300	 2-10	String constant, as comment.
03400	11-19	String Constants
03500	 3-15	String Declarations
03600	17-15	String Descriptors
03700	17-32	String Garbage Collection
03800	12-72	STRING MANIPULATION ROUTINES
03900	17-20	String Operations
04000	17-29	String Space
04100	17-15	STRINGS
04200	11- 1	<subscript_list>
04300	 9- 1	<substring_spec>
04400	 9-42	Substrings
04500	10- 2	Subtraction, sets
04600	 4- 1	<swap_statement>
04700	 4- 8	Swap Assignment
04800	 4- 2	Swap operator, restriction
04900	14- 1	<switch_spec>
05000	14- 1	<switches>
05100	14-13	Switches
     

00100	SAILON NO. 57.2					SAIL   19-1
00200	
00300	15-10	Symbols
00400	 3- 1	<synonym>
00500	 3- 1	<synonym_declaration>
00600	 3- 1	<synonym_list>
00700	 3-55	Synonyms
00800	12-68	Teletype I/O Functions
00900	 9- 1	<term>
01000	 9-33	Terms
01100	16- 1	THE SAIL CORE IMAGE (REQUIRED)
01200	10- 5	THIRD, of bracketed triple
01300	 7-12	Triples, bracketed
01400	 7-17	Triples, in FOREACH specifications
01500	11-18	TRUE, definition
01600	 3- 1	<type>
01700	 3- 1	<type_declaration>
01800	 3- 1	<type_qualifier>
01900	12-75	TYPE CONVERSION ROUTINES
02000	 3-11	Type Declarations
02100	 9-55	Unary Minus
02200	10- 2	Union, sets
02300	14- 1	<unslashed_switch_list>
02400	 3- 1	<upper_bound>
02500	13	USE OF DEFINE
02600	17- 1	User Table
02700	12-120	Usercon
02800	12-124	Usererr
02900	12-59	Useti, Useto
03000	13- 5	Using Macros
03100	14- 1	<valid_switch_name>
03200	 3-39	VALUE
03300	 3-53	VALUE
03400	 6- 5	VALUE, actual parameters
03500	11- 1	<variable>
03600	 3-11	Variables
03700	11- 2	Variables
03800	 8- 8	Warning Concerning Default Radix
03900	 5- 1	<while_statement>
04000	 5-16	While Statement
04100	12-48	Wordin
04200	12-53	Wordout
04300	 7-15	<binding_list>
04400